projects/rscriptd/rscriptd
projects/sgconf/sgconf
doc/xmlrpc-doc/book
+doc/help/book
General:
- * В init.d-скрипт для Gentoo добавлено явное указание PID-файла.
- * Исправлена синтаксическая ошибка в примере скрипта OnDisconnect для
- реализации связки шейпера, VPN и FreeRADIUS (спасибо Алексею Осипову
- за патч).
- * В каталоге conf-enabled.d симлинки теперь ссылаются по относительному
- пути (спасибо Алексею Осипову за патч).
- * Конфигурационные файлы переведены на английский язык.
- * В примеры скриптов добавлен шабанг.
+ * Стандартизован стиль именования параметров: SnakeCase.
+ * В документации к XML-RPC API добавлено пропущенное поле 'password' для
+ метода chg_admin.
+ * Приведена в порядок работа с сигналами. Теперь сигналы перехватываются
+ только из основного потока и перехватываются корректно, в отличие от
+ старых версий. Для остановки плагинов больше не используется pthread_kill,
+ т.к. плагины его все равно теперь игнорируют.
+ * Устаревшая функция usleep заменена на более продвинутую функцию
+ nanosleep в соответствии с POSIX.1-2008.
+ * Удалены странные, непонятные и ненужные комментарии в коде.
+ * Некоторые типы данных сделаны более "строгими".
+ * Добавлено несколько дополнительных проверочных утверждений.
+ * Упрощено API плагинов.
+ * Удален странный код.
+ * Большая часть кода приведена в соответствие с рекомендациями Скотта
+ Мейерса.
+ * Вычищена куча кода. Но это еще не конец.
Compilation:
- * При создании каталогов в процессе установки для них теперь вместо
- переменной BIN_MODE используется переменная DIR_MODE с правами на
- каталог.
- * Добавлены проверки наличия компилятора в системе.
- * При построении зависимостей больше не используется флаг -MG.
+ * При проверке условий сборки теперь используются переменные CC и CXX
+ вместо явного вызова gcc/g++.
+ * Если переменные CC и CXX не определены то используются gcc и g++ по
+ умолчанию.
+ * Добавлено разделение флагов на CFLAGS и CXXFLAGS. Теперь релиз
+ рекомендуется собирать так:
+ $ CFLAGS="-O2" CXXFLAGS="${CFLAGS}" ./build
+ * Флаг компиляторы -g3 заменен на -ggdb3 (все равно его поддерживает
+ и gcc, и clang и ekopath).
+ * Существенно переработана система сборки. Теперь она не сорит
+ заголовочными файлами и библотеками там где не нужно.
Libraries:
- * В библиотеке dotconfpp убрана глобальная зависимость от заголовочного
- файла mempool.h. Теперь для использования этой библиотеки этот
- заголовочный файл не требуется.
- * Удалены неиспользуемые библиотеки hostallow и common_settings.
- * Из названий некоторых библиотек убран префикс stg.
- * В библиотеке dotconfpp исправлен механизм сообщения об ошибках.
- * В библиотеке common исправлена ошибка в функции Encode12 которая
- приводила к неполному кодированию данных если в них встречаются нулевые
- байты.
+ * Использование динамических внутренних библиотек признано
+ нецелесообразным, возвращены старые-добрые a-файлы (последний раз они были
+ в версии 2.401).
+ * Добавлена специализация x2str для беззнаковых типов.
+ * Библиотеки crypto.lib и scriptexecuter.lib теперь содержат 100% кода на
+ языке C!
Plugins:
- * Убрана лишняя зависимость у плагина для MySQL.
- * В плагине файлового хранилища добавлен расширенный формат помесячной
- статистики (включены все поля из обычной статистики). Классический формат
- оставлен для совместимости.
- * В плагине XML-RPC API исправлено название поля (disabledetailstat ->
- disableddetailstat).
- * В плагине XML-RPC API исправлено название поля (tariff -> name).
- * В плагине XML-RPC API исправлена ошибка приводящая к невозможности
- удаления пользователя.
- * Переименованы некоторые методы в XML-RPC API:
- tariff_change -> chg_user_tariff;
- send_message -> send_user_message;
- add_cash -> add_user_cash;
- set_cash -> set_user_cash.
- * В методе info плагина XML-RPC API убрано кодирование названий полей
- dirNames.
- * В плагине XML-RPC API добавлено преобразование в юникод полей note,
- address, email, group и массива dirNames.
+ * В плагин для PostgreSQL добавлен параметр retries указывающий количество
+ повторных попыток установить соединение с БД.
+ * Оптимизирована логика работы RemoveDir - теперь он удаляет ваши каталоги
+ на 50% быстрее!
+ * Унифицированы имена параметров плагинов для работы с БД: Server,
+ Database, User, Password. Старые имена поддерживаются, но объявлены
+ устаревшими. В будущем будут удалены.
+ * Добавлен плагин для работы с snmpd по протоколу SMUX. Позволяет
+ производить мониторинг некоторых параметров системы:
+ - общее количество абонентов;
+ - количество абонентов online;
+ - количество авторизованных абонентов;
+ - количество абонентов с флагом alwaysOnline;
+ - количество абонентов с отрицательным балансом;
+ - количество абонентов с отключенной детальной статистикой;
+ - количество отключенных ("disabled") абонентов;
+ - количество "замороженных" ("passive") абонентов;
+ - количество абонентов с положительным кредитом;
+ - количество абонентов с положительным предоплаченным трафиком;
+ - количество абонентов меняющих тарифный план в следующем месяце;
+ - общее количество тарифов;
+ - количество абонентов потарифно;
+ - общее количество админов;
+ - общее количество сервисов;
+ - общее количество корпораций;
+ - общее количество правил классификации трафика.
+ * Добавлен шаблонный класс PLUGIN_CREATOR для универсального удобного
+ порождения плагинов.
+ * При немедленном изменении тарифа через XML-RPC API добавлен "сброс"
+ отложенного тарифа.
+ * Возможно исправлена ошибка приводящая к "зависаниям" плагина
+ конфигуратора.
+ * Исправлена утечка ресурсов (файловых дескрипторов) в плагине файлового
+ хранилища.
+ * Улучшены сообщения об ошибках авторизации, теперь в них на 73.1% больше
+ информации!
+ * В плагине для XML-RPC API вынужденно используется внешний сокет для
+ корректной остановки плагина. Привет мейнтейнерам Debian которые до сих
+ пор не обновили xmlrpc-c! Зато минус одно падение с SIGSEGV и General
+ Protection Fault при останове!
stargazer:
- * Изменен механизм работы с сообщениями пользователям. Теперь Staragzer не
- обращается постоянно к базе за списком сообщений перед попыткой отправки,
- а читает их при авторизации абонента и далее поддерживает у себя в памяти
- актуальный список.
- * Исправлена ошибка которая приводила к падению при попытке пользователя
- авторизоваться через FreeRADIUS с неправильным логином.
- * Исправлена ошибка которая приводила к неправильной передаче параметра
- "id" в rscriptd.
- * Добавлена возможность удаления из БД сообщений которые не были
- отправлены более указанного промежутка времени.
- * Исправлена ошибка которая приводила к массовым отключениям в rscriptd
- после массовых включений.
- * Исправлено преобразование кодировки (добавлена поддержка Украинского и
- Белорусского языков).
- * Исправлена дата старта таймера в режиме отладки.
- * Вызов localtime заменен на реэнтерабельный вызов localtime_r (устраняет
- потенциальные проблемы с многопоточностью).
- * Внутренние классы разделены на "интерфейсы" (абстрактные базовые классы)
- и реализацию. Теперь возможна сборка плагинов out of the box (вне дерева
- исходников Stargazer).
- * Из имен интерфейсных классов убран префикс BASE_. Так же переименованы
- заголовочные файлы с их определением.
- * Начат процесс замены usleep на nanosleep. usleep помечена как устаревшая
- в POSIX.2001.
- * Исправлена ошибка которая иногда приводила к тому что некоторые
- подсистемы стартовали до запуска внутреннего таймера, что могло привести
- к "зависанию" детальной статистики некоторых пользователей и "утечке"
- памяти.
- * Добавлена возможность отслеживать состояние поля connected класса USER
- посредством нотификаторов.
- * Общие заголовочные файлы перемещенны в подкаталог stg и добавлена их
- установка в /usr/include/stg.
+ * Исправлена ошибка приводящая к неправильному сообщению о причине
+ отключения.
+ * Убрано бесполезное изменение значения nice для процесса.
+ * Добавлены три возможных сценария снятия абонплаты:
+ - обычный;
+ - не снимать абонплату при отрицательном балансе;
+ - не снимать абонплату ели баланс при этом станет отрицательным.
+ * Добавлен параметр ReconnectOnTariffChange указывающий системе выполнять
+ переподключение абонента при изменении тарифа.
+ * Добавлена "подписка" на добавление и удаление тарифов.
+ * Управление авторизацией абонентов перемещено из класса USER в класс
+ USERS что позволило избавиться от дедлока в определенных условиях.
+ * Устранена возможность выгрузки активного плагина. Минус одно
+ потенциальное падение с SIGSEGV и General Protection Fault!
rscriptd:
- * Исправлена ошибка которая могла привести к "гонкам" (race conditions).
- * Удалено ожидание после перехода в режим дэмона.
- * Добавлено ожидание освобождения очереди сообщений при останове.
-
-sgauth:
- * Исправлена ошибка из-за которой авторизатор не стартовал (спасибо
- Алексею Осипову за патч).
- * Исправлено чтение конфигурационного файла по умолчанию (спасибо
- Алексею Осипову за патч).
- * Добавлена инициализация статистики нулями (если подключиться не удалось
- в таблице теперь выводятся нули вместо мусора).
- * Исправлено значение параметра ListenWebIP по умолчанию в
- конфигурационном файле.
-
-sgconf:
- * Исправлено преобразование кодировки (добавлена поддержка Украинского и
- Белорусского языков).
- * Добавлен флаг -E для управления тайм-аутом кредита.
+ * В примере конфигурационного файла для rscriptd путь /etc/rscriptd
+ заменен на /etc/stargazer.
-<chapter xml:id="ch1">
- <title>Назначение и возможности системы</title>
- <para>Система Stargazer (далее просто «система») предназначена для авторизации и учета трафика в локальных сетях. При написании данной системы была поставлена задача создать продукт, который отвечал бы требованиям большинства локальных сетей для учета в них трафика и средств клиентов, а также безопасной авторизации клиентов.</para>
- <para>Система построена по клиент-серверной технологии, что обеспечивает необходимую гибкость и быстродействие. В качестве сервера выступает машина с ОС Linux или FreeBSD и архитектурой x86/x86_64/SPARC. В качестве клиентов могут выступать машины как семейства Windows, так и клиенты с ОС GNU/Linux или FreeBSD. Так же клиентом может выступать любая ОС, в которой есть поддержка сетевых протоколов TCP-IP и WEB-броузер.</para>
- <para>Система имеет модульную структуру, что позволяет гибко изменять ее конфигурацию и функциональность.</para>
- <para>Основные возможности системы:</para>
- <itemizedlist mark="opencircle">
- <listitem><para>контроль над клиентами сети, их добавление, удаление, текущие корректировки;</para></listitem>
- <listitem><para>авторизация клиента, с последующим разрешением или запретом доступа в Internet;</para></listitem>
- <listitem><para>подсчет трафика по предварительно заданным направлениям и правилам;</para></listitem>
- <listitem><para>подсчет израсходованных клиентом средств и автоматическое отключение в случае их полного расходования;</para></listitem>
- <listitem><para>хранение дополнительной информации о клиенте, такой как домашний адрес, телефон и т.д.;</para></listitem>
- <listitem><para>автоматический пинг всех клиентов сети и вывод результатов на экран;</para></listitem>
- <listitem><para>ведение истории для всех клиентов;</para></listitem>
- <listitem><para>журналирование действий администраторов системы;</para></listitem>
- <listitem><para>оперативное предоставление клиенту информации о его трафике и наличии средств;</para></listitem>
- <listitem><para>формирование подробных отчетов о состоянии клиентов;</para></listitem>
- <listitem><para>подключаемые модули.</para></listitem>
- </itemizedlist>
-</chapter>
+<chapter xml:id="ch1">
+ <title>Назначение и возможности системы.</title>
+ <para>Система Stargazer (далее просто «система») предназначена для авторизации и учета трафика в локальных сетях. При написании данной системы была поставлена задача создать продукт, который отвечал бы требованиям большинства локальных сетей для учета в них трафика и средств клиентов, а также безопасной авторизации клиентов.</para>
+ <para>Система построена по клиент-серверной технологии, что обеспечивает необходимую гибкость и быстродействие. В качестве сервера выступает машина с ОС Linux или FreeBSD и архитектурой x86/x86_64/SPARC. В качестве клиентов могут выступать машины как семейства Windows, так и клиенты с ОС Linux или FreeBSD. Так же клиентом может выступать любая ОС, в которой есть поддержка сетевых протоколов TCP-IP и WEB-броузер.</para>
+ <para>Система имеет модульную структуру, что позволяет гибко изменять ее конфигурацию и функциональность.</para>
+ <para>Основные возможности системы:</para>
+ <itemizedlist mark="opencircle">
+ <listitem><para>контроль над клиентами сети, их добавление, удаление, текущие корректировки;</para></listitem>
+ <listitem><para>авторизация клиента, с последующим разрешением или запретом доступа в Internet;</para></listitem>
+ <listitem><para>подсчет трафика по предварительно заданным направлениям и правилам;</para></listitem>
+ <listitem><para>подсчет израсходованных клиентом средств и автоматическое отключение в случае их полного расходования;</para></listitem>
+ <listitem><para>хранение дополнительной информации о клиенте, такой как домашний адрес, телефон и т.д.;</para></listitem>
+ <listitem><para>автоматический пинг всех клиентов сети и вывод результатов на экран;</para></listitem>
+ <listitem><para>ведение истории для всех клиентов;</para></listitem>
+ <listitem><para>журналирование действий администраторов системы;</para></listitem>
+ <listitem><para>оперативное предоставление клиенту информации о его трафике и наличии средств;</para></listitem>
+ <listitem><para>формирование подробных отчетов о состоянии клиентов;</para></listitem>
+ <listitem><para>подключаемые модули;</para></listitem>
+ </itemizedlist>
+ </chapter>
\ No newline at end of file
<chapter xml:id="ch2">
- <title>Описание компонентов системы</title>
+ <title>Описание компонентов системы.</title>
<para>Составными компонентами системы являются:</para>
<orderedlist numeration="arabic">
- <listitem><para>сервер;</para></listitem>
- <listitem><para>конфигуратор;</para></listitem>
- <listitem><para>авторизатор.</para></listitem>
+ <listitem><para>Сервер;</para></listitem>
+ <listitem><para>Ð\9aонфигуратор;</para></listitem>
+ <listitem><para>Ð\90вторизатор.</para></listitem>
</orderedlist>
<para>Сервер – служит для авторизации клиентов, манипуляции правилами сетевого фильтра (firewall), подсчета трафика, выполнения финансовых операций, хранения информации о статистике и выдаче её клиентам и администраторам.</para>
<para>Конфигуратор – используют администраторы сети. Служит для просмотра и редактирования свойств клиентов. Конфигуратор является основным инструментарием для администрирования системы. Доступ к различным функциям разграничен для различных категорий администраторов. С помощью конфигуратора выполняются все финансовые операции с клиентскими счетами, так же просматривается подробная статистика клиентов. Конфигуратором настраиваются некоторые параметры сервера, например тарифные планы и администраторы.</para>
<para>Авторизатор – используется на клиентских машинах. С его помощью происходит авторизация клиента на сервере, получение права на доступ в Интернет или к другим ресурсам, которые разрешены администратором. Так же авторизатор позволяет клиенту просмотреть свою статистику и состояние денежных средств на счету.</para>
-</chapter>
+</chapter>
\ No newline at end of file
<chapter xml:id="ch3">
- <title>Установка системы</title>
- <para>Система обычно поставляется в виде 3 файлов: исходных кодов сервера, бинарной сборки конфигуратора и авторизатора.</para>
+ <title>Установка системы.</title>
+ <para>Система обычно поставляется в виде 3 файлов: исходных кодов сервера, бинарной сборки конфигуратора и авторизатора.</para>
<para>Стабильная версия сервера маркируется так: stg-A.B.src.tgz. A и B – старшая и младшая версия сервера. Промежуточные версии сервера имеют маркировку: stg-A.B-YYYY.MM.DD-HH.MM.SS.tgz. A и B – старшая и младшая версия сервера. YYYY.MM.DD-HH.MM.SS – дата и время сборки.</para>
<para>Установочный файл конфигуратора имеет маркировку: sgconfig-A.B.C.win.exe. A.B – старшая и младшая версия конфигуратора. C – версия протокола конфигуратора. Исходные коды конфигуратора имеют маркировку: sgconfig-A.B.C.src.rar.</para>
<para>Установочный файл авторизатора имеет маркировку: inetaccess-A.B.C.win.exe. A.B – старшая и младшая версия авторизатора. C – версия протокола авторизатора.</para>
<simplesect>
<title>Установка сервера</title>
- <programlisting linenumbering="numbered">
- tar -zxvf stg-A.B.src.tgz
- cd stg-A.B.src/projects/stargazer
- ./build
- make install
- </programlisting>
+<programlisting linenumbering="unnumbered">
+tar -zxvf stg-A.B.src.tgz
+cd stg-A.B.src/projects/stargazer
+./build
+make install
+</programlisting>
<para>Заголовок скрипта build содержит набор параметров сборки и установки:</para>
- <itemizedlist>
+ <itemizedlist mark="opencircle">
<listitem><para>LDFLAGS – дополнительные ключи компоновщика (ключи, предназначенные непосредственно ld указывать в виде -Wl,<ключ>);</para></listitem>
- <listitem><para>CXXFLAGS – дополнительные ключи компилятора;</para></listitem>
+ <listitem><para>CFLAGS, CXXFLAGS – дополнительные ключи компилятора;</para></listitem>
<listitem><para>PREFIX – префикс путей установки;</para></listitem>
<listitem><para>BIN_MODE – права доступа к бинарным файлам системы (0755 по умолчанию);</para></listitem>
<listitem><para>DATA_MODE – права доступа к файлам данных системы (0644 по умолчанию);</para></listitem>
<listitem><para>DIR_MODE — права доступа к каталогам системы (0755 по умолчанию);</para></listitem>
<listitem><para>OWNER – владелец файлов системы (root по умолчанию);</para></listitem>
- <listitem><para>FIREBIRD_GROUP – группа сервера СУБД Firebird (по умолчанию firebird);</para></listitem>
- <listitem><para>DB_ADDRESS – адрес БД (Firebird) системы ( по умолчанию "localhost:/var/stargazer/stargazer.fdb");</para></listitem>
- <listitem><para>DB_USER – пользователь БД (Firebird) системы (по умолчанию "stg");</para></listitem>
- <listitem><para>DB_PASSWORD – пароль пользователя БД (Firebird) системы (по умолчанию "123456");</para></listitem>
- <listitem><para>FIREBIRD_ISQL – путь к командному интерпретатору SQL СУБД Firebird (по умолчанию "/opt/firebird/bin/isql", пользователи Debian и, возможно, некоторых других дистрибутивов должны указать путь к утилите isql-fb);</para></listitem>
</itemizedlist>
- <para>Параметры указываются в формате <ИМЯ_ПАРАМЕТРА> = <ЗНАЧЕНИЕ_ПАРАМЕТРА></para>
- <para>В случае успешной сборки бинарных файлов сервера и их инсталляции в каталогах /etc и /var появится каталог stargazer с набором конфигурационных файлов. Бинарный файл установиться в каталог /usr/sbin с именем stargazer, библиотеки и модули установятся в каталог /usr/lib/stg/ а заголовочные файлы в каталог /usr/include/stg.</para>
- <para>Если сборка прошла без ошибок и необходимые файлы находятся в соответствующих каталогах, то установка считается успешно завершенной.</para>
- <para>Для удобства разработчиков и для создания багрепортов возможна сборка в отладочном режиме. Для этого скрипт ./build запускается с параметром debug. В этом режиме сборка не производится, а выполняется только конфигурирование. Для сборки отладочной версии необходимо выполнить команду make (gmake для BSD-систем). Также возможна раздельная установка бинарных файлов и файлов данных. Для этого в Makefile предусмотренны цели install-bin и install-data. make install-bin устанавливает только бинарные файлы (сервер, модули и библиотеки) и заголовочные файлы. make install-data устанавливает конфигурационные файлы и БД. По аналогии с целью install работает и цель uninstall. make uninstall удаляет сервер из системы. uninstall-bin и uninstall-data удаляют бинарные файлы и файлы данных соответственно.</para>
- <formalpara>
- <title>Внимание!</title>
- <para>Для успешной сборки сервера необходима правильно установленная библиотека LibExpat. (Поиск производится в /usr/lib и /usr/local/lib, но при желании с помощью переменных окружения CXXFLAGS и LDFLAGS можно указать и иное месторасположение библиотеки).</para>
- </formalpara>
- <para>Если в процессе сборки будет обнаружена правильно установленная библиотека fbclient (входит в стандартную поставку СУБД Firebird) в сборку будет включен модуль для работы с СУБД Firebird. Модуль поддерживает работу с СУБД Firebird версии 1.5 и выше.</para>
- <para>Если в процессе сборки будет обнаружена правильно установленная библиотека mysqlclient (входит в стандартную поставку СУБД MySQL) в сборку будет включен модуль для работы с СУБД MySQL. Модуль поддерживает работу с СУБД MySQL версии 4.0 и выше.</para>
- <para>Если в процессе сборки будет обнаружена библиотека pq в сборку будет включен модуль для работы с СУБД PostgreSQL. Модуль поддерживает работу с СУБД PostgreSQL версии 8.0 и выше.</para>
- <formalpara>
- <title>Примечание</title>
- <para>Если сборка завершилась неудачей, то необходимо проверить доступность библиотеки LibExpat. Пользователи ОС Linux могут выполнить команду ldconfig -p | grep libexpat.so. Если она выведет нечто похожее на
- <programlisting linenumbering="unnumbered">
- # ldconfig -p | grep libexpat.so
- libexpat.so.1 (libc6) => /usr/lib/libexpat.so.1
- libexpat.so (libc6) => /usr/lib/libexpat.so
- </programlisting>
- значит библиотека доступна. Если вывод будет пустой – библиотека в системе не найдена. Для пользователей ОС FreeBSD можно выполнить команду ls /usr/lib | grep libexpat.so. Если она выведет нечто похожее на
- <programlisting linenumbering="unnumbered">
- # ls /usr/lib | grep libexpat.so
- libexpat.so
- libexpat.so.4
- </programlisting>
- значит библиотека доступна. Если вывод пустой – скорее всего библиотеки в системе нет или она установлена неправильно. Возможно, библиотека установлена в другое место. Если это так – достаточно при выполнении скрипта build в CXXFLAGS с помощью ключа -I указать путь к заголовочным файлам библиотеки, а в LDLFAGS с помощью ключа -L указать путь к самой библиотеке. Для поиска библиотеки можно использовать команды locate, slocate, whereis или find. Если библиотека в системе отсутствует – установите ее используя Ваш пакетный менеджер (apt (Debian, Ubuntu), rpm (RPM-based дистрибутивы), emerge (Gentoo) или др.). Так же библиотеку можно установить из исходных кодов, доступных на странице http://sourceforge.net/projects/expat/.</para>
- </formalpara>
- <para>Для использования СУБД Firebird в качестве хранилища необходимо наличие библиотеки fbclient. Проверка может быть выполнена аналогично библиотеке LibExpat: ldconfig -p | grep libfbclient.so для ОС Linux и ls /usr/lib | grep libfbclient.so для ОС FreeBSD. Некоторые дистрибутивы позволяют установить ее отдельно от СУБД (например, в Ubuntu соответствующий пакет называется libfbclient1), некоторые – только в составе сервера (например, Gentoo). Исходные коды СУБД Firebird доступны для скачивания со страницы http://www.firebirdsql.org/index.php?op=files. Необходимо заметить, что сами разработчики СУБД Firebird не разделяют свой продукт на клиентскую и серверную части. По этому архивы исходных кодов содержат и сервер СУБД, и консольный клиент (командный интерпретатор SQL) и клиентскую библиотеку.</para>
- <para>Для использования СУБД MySQL в качестве хранилища необходимо наличие библиотеки mysqlclient. Проверка выполняется аналогично первым двум: ldconfig -p | grep libmysqlclient_r.so для ОС Linux и ls /usr/lib | grep libmysqlclient_r.so для ОС FreeBSD. Так же проверку можно выполнить с помощью утилиты mysql_config. Ее вызов с ключем --libs_r должен выдать что-то похожее на
- <programlisting linenumbering="unnumbered">
- $ mysql_config --libs
- -Wl,-O1 -rdynamic -L/usr/lib/mysql -lmysqlclient -lz -lcrypt -lnsl -lm -L/usr/lib -lssl -lcrypto
- </programlisting>
- Необходима именно реентерабельная версия библиотеки, т.к. Сам плагин не имеет блокировок. Некоторые дистрибутивы позволяют установить ее отдельно от СУБД (например, в Ubuntu соответствующие пакеты называются libmysqlclient15-dev и libmysqlclient15off), некоторые – только в составе сервера (например, Gentoo). Исходные коды открытой/свободной версии СУБД MySQL доступны для скачивания со страницы http://dev.mysql.com/downloads/mysql/5.0.html. Необходимо заметить, что сами разработчики СУБД MySQL не разделяют свой продукт на клиентскую и серверную части. По этому архивы исходных кодов содержат и сервер СУБД MySQL, и консольный клиент (командный интерпретатор SQL) и клиентскую библиотеку.</para>
- <para>Для использования СУБД PostgreSQL необходимо наличие библиотеки pq. Проверка выполняется аналогично предыдущим: ldconfig -p | grep libpq.so для ОС Linux и ls /usr/lib | grep libpq.so для ОС FreeBSD. Так-же проверку можно выполнить с использованием утилиты pg_config или pkg_config. Ее вызов с ключем --libdir выдать что-то похожее на
- <programlisting numbered="unnumbered">
- $ pg_config --libdir
- /usr/lib
- </programlisting>
- Обычно библиотека устанавливается отдельно от самой СУБД. Например, в Debian соответствующий пакет называется libpq5 и libpq-dev. Исходные коды библиотеки можно загрузить со страницы http://www.postgresql.org/ftp/source/. Необходимо заметить, что сами разработчики СУБД PostgreSQL не разделяют свой продукт на клиентскую и серверную части. По этому архивы исходных кодов содержат и сервер СУБД PostgreSQL, и консольный клиент (командный интерпретатор SQL) и клиентскую библиотеку.</para>
- </simplesect>
- <simplesect>
- <title>Установка авторизатора и конфигуратора</title>
- <para>Для установки конфигуратора необходимо запустить установочный файл и следовать вопросам мастера установки.</para>
- <para>Для установки авторизатора необходимо запустить установочный файл и следовать вопросам мастера установки.</para>
- </simplesect>
- <simplesect>
+ <para>Параметры указываются в формате <ИМЯ_ПАРАМЕТРА> = <НАЧЕНИЕ_ПАРАМЕТРА>. CFLAGS, CXXFLAGS и LDFLAGS можно передавать в скрипт build из окружения. Например так:</para>
+<programlisting linenumbering="unnumbered">
+CFLAGS=-O2 CXXFLAGS=-O2 LDFLAGS=-Wl,--as-needed ./build
+</programlisting>
+ <para>Следует учитывать тот факт что исходный код сервера содержит в себе модули написанные как на C++ так и на C, по этому необходимо передавать флаги компилятора через обе переменные: CFLAGS и CXXFLAGS. При сборке сервера для использования на «боевом» сервере (или для включения в дистрибутив) настоятельно рекомендуется использовать оптимизацию (флаг компилятора -O). Обычно достаточно указать -O2. При отладочной сборке, в общем случае, оптимизацию лучше не включать.</para>
+ <para>В случае успешной сборки бинарных файлов сервера и их инсталляции в каталогах /etc и /var появится каталог stargazer с набором конфигурационных файлов. Бинарный файл установиться в каталог /usr/sbin с именем stargazer, библиотеки и модули установятся в каталог /usr/lib/stg/ а заголовочные файлы в каталог /usr/include/stg.</para>
+ <para>Если сборка прошла без ошибок и необходимые файлы находятся в соответствующих каталогах, то установка считается успешно завершенной.</para>
+ <para>Для удобства разработчиков и для создания багрепортов возможна сборка в отладочном режиме. Для этого скрипт ./build запускается с параметром debug. В этом режиме сборка не производится, а выполняется только конфигурирование. Для сборки отладочной версии необходимо выполнить команду make (gmake для BSD-систем). Также возможна раздельная установка бинарных файлов и файлов данных. Для этого в Makefile предусмотрены цели install-bin и install-data. make install-bin устанавливает только бинарные файлы (сервер, модули и библиотеки) и заголовочные файлы. make install-data устанавливает конфигурационные файлы и файловую БД. По аналогии с целью install работает и цель uninstall. make uninstall удаляет сервер из системы. uninstall-bin и uninstall-data удаляют бинарные файлы и файлы данных соответственно.</para>
+ <para>При обновлении системы настоятельно рекомендуется использовать команду make install-bin.</para>
+ <formalpara>
+ <title>Внимание!</title>
+ <para>Для успешной сборки сервера необходима правильно установленная библиотека LibExpat. (Поиск производится в /usr/lib и /usr/local/lib, но при желании с помощью переменных окружения CFLAGS/CXXFLAGS и LDFLAGS можно указать и иное месторасположение библиотеки).</para>
+ </formalpara>
+ <para>Если в процессе сборки будет обнаружена правильно установленная библиотека fbclient (входит в стандартную поставку СУБД Firebird) в сборку будет включен модуль для работы с СУБД Firebird. Модуль поддерживает работу с СУБД Firebird версии 1.5 и выше.</para>
+ <para>Если в процессе сборки будет обнаружена правильно установленная библиотека mysqlclient (входит в стандартную поставку СУБД MySQL) в сборку будет включен модуль для работы с СУБД MySQL. Модуль поддерживает работу с СУБД MySQL версии 4.0 и выше.</para>
+ <para>Если в процессе сборки будет обнаружена библиотека pq в сборку будет включен модуль для работы с СУБД PostgreSQL. Модуль поддерживает работу с СУБД PostgreSQL версии 8.0 и выше.</para>
+ <formalpara>
+ <title>Примечание:</title>
+ <para>Если сборка завершилась неудачей, то необходимо проверить доступность библиотеки LibExpat. Пользователи ОС Linux могут выполнить команду ldconfig -p | grep libexpat.so. Если она выведет нечто похожее на
+<programlisting linenumbering="unnumbered">
+# ldconfig -p | grep libexpat.so
+libexpat.so.1 (libc6) => /usr/lib/libexpat.so.1
+libexpat.so (libc6) => /usr/lib/libexpat.so
+</programlisting>
+ значит библиотека доступна. Если вывод будет пустой – библиотека в системе не найдена. Для пользователей ОС FreeBSD можно выполнить команду ls /usr/lib | grep libexpat.so. Если она выведет нечто похожее на
+<programlisting linenumbering="unnumbered">
+$ ls /usr/lib | grep libexpat.so
+libexpat.so
+libexpat.so.4
+</programlisting>
+ значит библиотека доступна. Если вывод пустой – скорее всего библиотеки в системе нет или она установлена неправильно.</para>
+ </formalpara>
+ <para>Возможно, библиотека установлена в другое место. Если это так – достаточно при выполнении скрипта build в CFLAGS/CXXFLAGS с помощью ключа -I указать путь к заголовочным файлам библиотеки, а в LDLFAGS с помощью ключа -L указать путь к самой библиотеке. Для поиска библиотеки можно использовать команды locate, slocate, whereis или find. Если библиотека в системе отсутствует – установите ее используя Ваш пакетный менеджер (apt (Debian, Ubuntu), rpm (RPM-based дистрибутивы), emerge (Gentoo) или др.). Так же библиотеку можно установить из исходных кодов, доступных на странице http://sourceforge.net/projects/expat/.</para>
+ <para>Для использования СУБД Firebird в качестве хранилища необходимо наличие библиотеки fbclient. Проверка может быть выполнена аналогично библиотеке LibExpat: ldconfig -p | grep libfbclient.so для ОС Linux и ls /usr/lib | grep libfbclient.so для ОС FreeBSD. Некоторые дистрибутивы позволяют установить ее отдельно от СУБД (например, в Ubuntu соответствующий пакет называется libfbclient1), некоторые – только в составе сервера (например, Gentoo). Исходные коды СУБД Firebird доступны для скачивания со страницы http://www.firebirdsql.org/index.php?op=files. Необходимо заметить, что сами разработчики СУБД Firebird не разделяют свой продукт на клиентскую и серверную части. По этому архивы исходных кодов содержат и сервер СУБД, и консольный клиент (командный интерпретатор SQL) и клиентскую библиотеку.</para>
+ <para>Для использования СУБД MySQL в качестве хранилища необходимо наличие библиотеки mysqlclient. Проверка выполняется аналогично первым двум: ldconfig -p | grep libmysqlclient_r.so для ОС Linux и ls /usr/lib | grep libmysqlclient_r.so для ОС FreeBSD. Так же проверку можно выполнить с помощью утилиты mysql_config. Ее вызов с ключем --libs_r должен выдать что-то похожее на
+<programlisting linenumbering="unnumbered">
+$ mysql_config --libs
+-Wl,-O1 -rdynamic -L/usr/lib/mysql -lmysqlclient -lz -lcrypt -lnsl -lm -L/usr/lib -lssl -lcrypto
+</programlisting>
+ Необходима именно реентерабельная версия библиотеки, т.к. Сам плагин не имеет блокировок. Некоторые дистрибутивы позволяют установить ее отдельно от СУБД (например, в Ubuntu соответствующие пакеты называются libmysqlclient15-dev и libmysqlclient15off), некоторые – только в составе сервера (например, Gentoo). Исходные коды открытой/свободной версии СУБД MySQL доступны для скачивания со страницы http://dev.mysql.com/downloads/mysql/5.0.html. Необходимо заметить, что сами разработчики СУБД MySQL не разделяют свой продукт на клиентскую и серверную части. По этому архивы исходных кодов содержат и сервер СУБД MySQL, и консольный клиент (командный интерпретатор SQL) и клиентскую библиотеку.</para>
+ <para>Для использования СУБД PostgreSQL необходимо наличие библиотеки pq. Проверка выполняется аналогично предыдущим: ldconfig -p | grep libpq.so для ОС Linux и ls /usr/lib | grep libpq.so для ОС FreeBSD. Так-же проверку можно выполнить с использованием утилиты pg_config или pkg_config. Ее вызов с ключем --libdir выдать что-то похожее на
+<programlisting numbered="unnumbered">
+$ pg_config --libdir
+/usr/lib
+</programlisting>
+ Обычно библиотека устанавливается отдельно от самой СУБД. Например, в Debian соответствующий пакет называется libpq5 и libpq-dev. Исходные коды библиотеки можно загрузить со страницы http://www.postgresql.org/ftp/source/. Необходимо заметить, что сами разработчики СУБД PostgreSQL не разделяют свой продукт на клиентскую и серверную части. По этому архивы исходных кодов содержат и сервер СУБД PostgreSQL, и консольный клиент (командный интерпретатор SQL) и клиентскую библиотеку.</para>
+ </simplesect>
+ <simplesect>
+ <title>Установка авторизатора и конфигуратора</title>
+ <para>Для установки конфигуратора необходимо запустить установочный файл и следовать вопросам мастера установки.</para>
+ <para>Для установки авторизатора необходимо запустить установочный файл и следовать вопросам мастера установки.</para>
+ </simplesect>
+ <simplesect>
<title>Запуск сервера</title>
- <para>При запуске в качестве первого параметра можно указать путь к директории, где расположен файл stargazer.conf. По умолчанию при запуске без параметров система ищет файл в каталоге /etc/stargazer. Например если файл stargazer.conf находится в каталоге /etc/stargazer2, то для запуска системы с чтением настройки из этого каталога следует запустить сервер таким образом: ./stargazer /etc/stargazer2. Для просмотра, работает ли сервер, необходимо выполнить команду: ps –x | grep stargazer. В случае если сервер успешно был запущен и работает то результат команды должен быть примерно таким:</para>
- <programlisting linenumbering="unnumbered">
- 4818 ? S< 0:32 ./stargazer /etc/stargazer
- 4819 ? S 0:00 stg-exec /etc/stargazer
- </programlisting>
- <para>Следует отметить что в выводе предыдущей команды должно присутствовать не менее двух строк. То есть, первая строка в данном примере – это процесс сервера, вторая – процесс исполнителя скриптов. Если присутствует только строка с именем stg-exec или не имеется строк вовсе, то сервер не запущен или имеются проблемы в его работе. Для диагностики ошибок при запуске сервера необходимо просмотреть содержимое журнала сервера биллинга (/var/log/stargazer.log) или же системный журнал (обычно /var/log/messages).</para>
- <para>Сервер ведет журнал своих действий, куда заносятся все сообщения системы. По умолчанию лог файл находится в каталоге /var/log и имеет название stargazer.log. Если при запуске сервера возникла какая-то ошибка, то необходимо просмотреть файл журнала и исправить ошибку. В случае если серверу не удается записать сообщения в указанный файл, он пытается писать сообщения в syslog, обычно записи syslog находяться в /var/log/messages.</para>
- </simplesect>
-</chapter>
+ <para>При запуске в качестве первого параметра можно указать путь к директории, где расположен файл stargazer.conf. По умолчанию при запуске без параметров система ищет файл в каталоге /etc/stargazer. Например если файл stargazer.conf находится в каталоге /etc/stargazer2, то для запуска системы с чтением настройки из этого каталога следует запустить сервер таким образом: /usr/sbin/stargazer /etc/stargazer2.</para>
+ <para>При использовании на “боевом” сервере настоятельно рекомендуется использовать init.d-скрипты для запуска, останова, перезапуска и реконфигурирования сервера. Заготовки скриптов для дистрибутивов Ubuntu, Suse и Gentoo входят в стандартную поставку и расположены в каталоге projects/stargazer/inst/linux/etc/init.d. Уважайте себя и других людей, которые, возможно, завтра будут администрировать этот сервер.</para>
+ <para>Для просмотра, работает ли сервер, необходимо выполнить команду: ps –x | grep stargazer | grep -v grep. В случае если сервер успешно был запущен и работает то результат команды должен быть примерно таким:</para>
+<programlisting linenumbering="unnumbered">
+4818 ? S< 0:32 ./stargazer /etc/stargazer
+4819 ? S 0:00 stg-exec /etc/stargazer
+</programlisting>
+ <para>Следует отметить что в выводе указанной выше команды должно присутствовать не менее двух строк. То есть, первая строка в данном примере – это процесс сервера, вторая – процесс исполнителя скриптов. Если присутствует только строка с именем stg-exec или не имеется строк вовсе, то сервер не запущен или имеются проблемы в его работе. Для диагностики ошибок при запуске сервера необходимо просмотреть содержимое журнала сервера биллинга (/var/log/stargazer.log) или же системный журнал (обычно /var/log/messages).</para>
+ <para>Сервер ведет журнал своих действий, куда заносятся все сообщения системы. По умолчанию лог файл находится в каталоге /var/log и имеет название stargazer.log. Если при запуске сервера возникла какая-то ошибка, то необходимо просмотреть файл журнала и исправить ошибку. В случае если серверу не удается записать сообщения в указанный файл, он пытается писать сообщения в syslog, обычно записи syslog находятся в /var/log/messages.</para>
+ </simplesect>
+</chapter>
\ No newline at end of file
<chapter xml:id="ch4">
- <title>Настройка системы</title>
- <para>После инсталляции система должна быть подвергнута процедуре настройки. Обычно следует начинать с настройки сервера.</para>
- <para>Основные конфигурационные файлы сервера по умолчанию находятся в каталоге /etc/stargazer. Они включают в себя: основной конфигурационный файл stargazer.conf, файл описания направлений тарификации rules, набор скриптов On* и два каталога — conf-available.d и conf-enabled.d, содержащих конфигурационные файлы отдельных модулей. Для включения какого-либо модуля нужно сделать символическую ссылку на его конфигурационный файл в каталоге conf-enabled.d или прописать его конфигурационную секцию в разделе <Modules> файла stargazer.conf.</para>
- <simplesect>
- <title>Настройка конфигурационного файла /etc/stargazer/stargazer.conf</title>
- <para>Файл имеет текстовый формат, содержащий пары ПАРАМЕТР = ЗНАЧЕНИЕ и секции <ИМЯ_СЕКЦИИ ПАРАМЕТРЫ_СЕКЦИИ>. Комментарии в файле начинаются с символа #. В файле описываются общие параметры, которые являются глобальными значениями для всего сервера биллинга, а также параметры соответствующих модулей. Параметры модулей должны быть заключены в секции:</para>
- <programlisting linenumbering="unnumbered">
- <Module [имя модуля(имя файла модуля без mod_ и без .so)]>
+ <title>Настройка системы</title>
+ <para>После инсталляции система должна быть подвергнута процедуре настройки. Обычно следует начинать с настройки сервера.</para>
+ <para>Основные конфигурационные файлы сервера по умолчанию находятся в каталоге /etc/stargazer. Они включают в себя: основной конфигурационный файл stargazer.conf, файл описания направлений тарификации rules, набор скриптов On* и два каталога — conf-available.d и conf-enabled.d, содержащих конфигурационные файлы отдельных модулей. Для включения какого-либо модуля нужно сделать символическую ссылку на его конфигурационный файл в каталоге conf-enabled.d или прописать его конфигурационную секцию в разделе <Modules> файла stargazer.conf.</para>
+ <simplesect>
+ <title>Настройка конфигурационного файла /etc/stargazer/stargazer.conf </title>
+ <para>Файл имеет текстовый формат, содержащий пары ПАРАМЕТР = ЗНАЧЕНИЕ и секции <ИМЯ_СЕКЦИИ ПАРАМЕТРЫ_СЕКЦИИ>. Комментарии в файле начинаются с символа #. В файле описываются общие параметры, которые являются глобальными значениями для всего сервера биллинга, а также параметры соответствующих модулей. Параметры модулей должны быть заключены в секции:</para>
+<programlisting linenumbering="unnumbered">
+<Module имя_модуля>
+список параметров модуля
+</Module>
+</programlisting>
+ <para>Имя модуля представляет собой имя файла этого модуля без префикса mod_ и суффикса .so. Например, секция конфигурации модуля remote_script (имя файла: mod_remote_script.so) может выглядеть так:</para>
+<programlisting linenumbering="unnumbered">
+<Module remote_script>
+SendPeriod = 15
+SubnetFile = subnets
+Password = 123456
+UserParams = Cash Tariff EnabledDirs
+Port = 9999
+</Module>
+</programlisting>
+ <para>Описание глобальных параметров параметров:</para>
+ <itemizedlist mark="opencircle">
+ <listitem><para>Rules – обязательный параметр, указывающий серверу, где находится файл с правилами для подсчета трафика клиентов. Стандартное значение: /etc/stargazer/rules.</para></listitem>
+ <listitem><para>LogFile – обязательный параметр, указывающий серверу расположение файла, в который будут заноситься все сообщения системы. Стандартное значение: /var/log/stargazer.log.</para></listitem>
+ <listitem><para>PidFile — не обязательный параметр, указывающий серверу где находится файл хранящий PID (идентификатор процесса) дэмона. По умолчанию это /var/run/stargazer.pid. Используется скриптами запуска/останова.</para></listitem>
+ <listitem><para>ModulesPath – обязательный параметр, указывающий серверу путь, где находятся подключаемые модули (плагины). Стандартное значение: /usr/lib/stg.</para></listitem>
+ <listitem><para>DetailStatWritePeriod – обязательный параметр, указывающий серверу через какое время должна записываться детальная статистика клиента. Стандартное значение: 1/6. Данный параметр может принимать следующие значения: 3 - раз в три часа, 2 - раз в два часа, 1 - раз в чаc, 1/2 - раз в пол часа, 1/4 - раз в 15 минут, 1/6 - раз в 10 минут.</para></listitem>
+ <listitem><para>StatWritePeriod – не обязательный параметр, указывающий серверу периодичность записи в БД информации о статистике пользователя в минутах. При большом количестве пользователей эту величину стоит увеличить, так как запись в БД может занимать длительное время. По умолчанию имеет значение 10.</para></listitem>
+ <listitem><para>DayFee – обязательный параметр, указывающий серверу, в какой день месяца снимать с клиентских счетов сумму абонплаты, в соответствии с тарифными планами клиентов. Может принимать значения от 0 до 31, стандартное значение: 1. Следует помнить, что в некоторых месяцах не более 28 дней. Значение 0 соответствует последнему дню месяца по календарю.</para></listitem>
+ <listitem><para>DayResetTraff – обязательный параметр, указывающий серверу в какой день месяца сбрасывать помесячную статистику клиентов и осуществлять переход на новый тариф, если он был изменен у клиента. Может принимать значения от 0 до 31, стандартное значение: 1. Следует помнить, что в некоторых месяцах не более 28 дней. Значение 0 соответствует последнему дню месяца по календарю.</para></listitem>
+ <listitem><para>SpreadFee – обязательный параметр, указывающий серверу производить ли «размазанное» снятие абонплаты. Может принимать значения yes и no. При указании значения yes сумма абонплаты указанная в тарифе пользователя будет сниматься не раз в месяц, а каждый день равными долями. Стандартное значение: no.</para></listitem>
+ <listitem><para>FreeMbAllowInet – обязательный параметр, указывающий серверу выполнять ли для пользователя скрипт OnConnect, если у него на балансе отсутствуют средства, но остался предоплаченный трафик. Может принимать значения yes и no. Стандартное значение: no.</para></listitem>
+ <listitem><para>WriteFreeMbTraffCost – обязательный параметр, определяющий как будет писаться стоимость трафика в детальной статистике. Может принимать значения yes и no, стандартное значение: no. При указании значения yes в детальной статистике пользователя стоимость трафика будет писаться в любом случае, даже если он попадает в FreeMb. При указании значения no доя исчерпания FreeMb в детальной статистике будет указана нулевая стоимость трафика.</para></listitem>
+ <listitem><para>DayFeeIsLastDay – обязательный параметр, указывающий серверу когда снимать абонплату. Может принимать значения yes и no, стандартное значение: yes. Это влияет на то, как будет снята абонплата (АП) при переходе на новый тариф. Если у пользователя был тариф A с АП=100 и он хочет перейти на тариф B с АП=200, то при переходе на новый тариф со счета пользователя снимется 100, если указано значение yes (абонплата снята до смены тарифа), и 200, если указано значение no (абонплата снята перед сменой тарифа).</para></listitem>
+ <listitem><para>ExecutersNum – не обязательный параметр который определяющий сколько скриптом может выполняться одновременно (регулирует количество процессов stg-exec). По умолчанию имеет значение 1. Если выполнение ваших скриптов занимает много времени имеет смысл увеличить это значение. Каждый исполнитель скриптов блокируется на время, пока отработает скрипт. Если исполнителей несколько — они принимают скрипты на выполнение по принципу «кто успел».</para></listitem>
+ <listitem><para>StgMsgKey – не обязательный параметр отвечающий за идентификатор очереди сообщений для исполнителя скриптов. По умолчанию данный параметр имеет значение 5555. Рекомендуется не изменять значение параметра без нужды. Его изменение целесообразно лишь в том случае, если в системе требуется запустить более одной копии сервера биллинга.</para></listitem>
+ <listitem><para>ShowFeeInCash – не обязательный параметр, определяющий как будет показано состояние счета абонента в авторизаторе и сколько денег ему будет разрешено использовать в текущем месяце. Может принимать значения yes и no, по умолчанию имеет значение yes. При указании no в авторизаторе будет показано состояние счета без учета следующего снятия абонплаты. Так же эти деньги нельзя будет использовать для оплаты трафика в текущем месяце. Пример: у абонента на счету 200 денег при абонплате в 50 денег — в этом случае ему будет показано 150 денег в авторизаторе и он сможет в текущем месяце израсходовать только 150 денег, но снятие абонплаты не уведет его в «минус».</para></listitem>
+ <listitem><para>FullFee – не обязательный параметр, указывающий серверу снимать полную абонплату, даже если учетная запись абонента была заморожена (или не существовала) часть учетного периода. Принимает значения yes и no, по умолчанию установлен в no.</para></listitem>
+ <listitem><para>MessagesTimeout — не обязательный параметр, устанавливающий время жизни не отправленных сообщений абонентам. Время указывается в сутках. При превышении этого времени сообщение будет удалено, в т. ч. из БД. Если указано значение 0 то не отправленные сообщения никогда не будут удаляться из базы (в частности, это приведет к постепенному росту размера базы, увеличению нагрузки на сервер при авторизации абонентов и к тому что долго отсутствовавший абонент при авторизации получит все пропущенные сообщения). По умолчанию имеет значение 0.</para></listitem>
+ <listitem><para>FeeChargeType — не обязательный параметр, регулирующий процесс снятия абонплаты. Может принимать значения 0, 1 и 2, по умолчанию имеет значение 0. При значении 0 абонплата снимается как обычно, при значении 1 абонплата снимается только если баланс пользователя положительный или равен нулю, при значении 2 абонплата снимается только если баланс пользователя больше или равен абонплате. Значение 2 следует использовать с осторожностью, т. к. при этом на безлимитных тарифах абоненты получат услугу бесплатно.</para></listitem>
+ <listitem><para>ReconnectOnTariffChange — не обязательный параметр, указывающий серверу выполнить переподключение пользователя при смене тарифа. Может принимать значения yes и no, по умолчанию имеет значение no. При указании значения yes подключенные пользователи будут отключены непосредственно перед сменой тарифа и подключены сразу после нее. Может быть полезно для управления шейпером.</para></listitem>
+ <listitem><para>Для именования направлений учета трафика в конфигурационном файле используется секция DirNames:</para></listitem>
+<programlisting linenumbering="unnumbered">
+<DirNames>
+DirName0 = «ИМЯ НАПРАВЛЕНИЯ»
+...
+DirName9 = ПОСЛЕДНЕЕ_НАПРАВЛЕНИЕ
+</DirNames>
+</programlisting>
+ <para>Всего предусмотрено 10 направлений с нумерацией от 0 до 9. Направления, наименование которых состоит из нескольких слов, должны быть заключены в кавычки. Если наименование направления не указано, то система считает что данное направление не используется и не будет производить по нему никаких действий. Пример: DirName0 = Мир, DirName5 = "Локальные игры". Необходимо заметить, что текущая версия системы требует, чтобы имена направлений были указаны в кодировке KOI8-R. В противном случае абоненты не смогут их прочитать в статистике авторизатора, а администраторы — в конфигураторе.</para>
+ <para>Настройки всех модули (кроме store module), которые необходимо подключить к серверу в момент старта должны быть указанны внутри секции Modules:</para>
+<programlisting linenumbering="unnumbered">
+<Modules>
+<Module имя_модуля>
+список параметров модуля
+</Modules>
- </Module>
- </programlisting>
- <para>Описание глобальных параметров параметров:</para>
- <itemizedlist mark="opencircle">
- <listitem><para>Rules – параметр, указывающий серверу, где находится файл с правилами для подсчета трафика клиентов, по умолчанию Rules=/etc/stargazer/rules</para></listitem>
- <listitem><para>LogFile – параметр, указывающий серверу расположение файла, в который будут заноситься все сообщения системы, по умолчанию LogFile=/var/log/stargazer.log</para></listitem>
- <listitem><para>PidFile — параметр, указывающий серверу где находится файл хранящий PID (идентификатор процесса) дэмона, по умолчанию это /var/run/stargazer.pid. Используется скриптами запуска/останова.</para></listitem>
- <listitem><para>ModulesPath – параметр, указывающий серверу путь, где находятся подключаемые модули (плагины). По умолчанию ModulesPath = /usr/lib/stg.</para></listitem>
- <listitem><para>DetailStatWritePeriod – параметр, указывающий серверу через какое время должна записываться детальная статистика клиента, по умолчанию StatTime=1/6. Данный параметр может принимать следующие значения: 3 - раз в три часа, 2 - раз в два часа, 1 - раз в чаc, 1/2 - раз в пол часа, 1/4 - раз в 15 минут, 1/6 - раз в 10 минут.</para></listitem>
- <listitem><para>StatWritePeriod – параметр, указывающий серверу периодичность записи в БД информации о статистике пользователя (в минутах). При большом количестве пользователей эту величину стоит увеличить, так как запись в БД может занимать длительное время. По умолчанию StatWritePeriod = 10.</para></listitem>
- <listitem><para>DayFee – параметр, показывающий серверу, в какой день месяца снимать с клиентских счетов сумму абонплаты, в соответствии с тарифными планами клиентов. По умолчанию DayFee=21. Следует помнить, что в некоторых месяцах не более 28 дней. Данный параметр также может принять значение 0; если параметр равен 0, тогда система выполнит действия в последний день текущего месяца; определение последнего дня месяца проводится автоматически.</para></listitem>
- <listitem><para>DayResetTraff – параметр указывает серверу в какой день месяца очищать статистику клиентов; так же в этот день сервер осуществляет переход на новый тариф, если он был изменен у клиента. По умолчанию DayResetTraff = 28. Следует помнить, что в некоторых месяцах не более 28 дней. Данный параметр также может принять значение 0; если параметр равен 0, тогда система выполнит действия в последний день текущего месяца; определение последнего дня месяца проводится автоматически.</para></listitem>
- <listitem><para>SpreadFee – параметр, указывающий серверу, производить ли «размазанное» снятие абонплаты. Т. е. сумма абонплаты указанная в тарифе пользователя будет сниматься не раз в месяц, а каждый день ровными долями. По умолчанию SpreadFee = no.</para></listitem>
- <listitem><para>FreeMbAllowInet – параметр, указывающий серверу выполнять ли для пользователя скрипт OnConnect, если у него на балансе отсутствуют средства, но остался предоплаченный трафик. По умолчанию FreeMbAllowInet = no.</para></listitem>
- <listitem><para>WriteFreeMbTraffCost – параметр, определяющий, что будет писаться в стоимость трафика в детальной статистике. Если у клиента еще есть предоплаченный трафик и WriteFreeMbTraffCost = no, то в детальную статистику будет записываться стоимость со значением = 0. Если у пользователя уже нет предоплаченного трафика и WriteFreeMbTraffCost = no, то в детальную статистику будет записана стоимость трафика. При WriteFreeMbTraffCost = yes стоимость трафика будет записана в любом случае. По умолчанию WriteFreeMbTraffCost = no.</para></listitem>
- <listitem><para>DayFeeIsLastDay – параметр, указывающий серверу, когда абонплата снимается в последний (yes) или первый (no) день учетного периода. Это влияет на то, как будет снята абонплата (АП) при переходе на новый тариф. Если у пользователя был тариф A с АП=100 и он хочет перейти на тариф B с АП=200, то при переходе на новый тариф со счета пользователя снимется 100, если DayFeeIsLastDay = yes, и 200, если DayFeeIsLastDay = no. По умолчанию DayFeeIsLastDay = yes.</para></listitem>
- <listitem><para>ExecutersNum – параметр который показывает, сколько процессов исполнителя скриптов может быть запущено одновременно. Количество процессов означает сколько скриптов могут выполнятся одновременно. По умолчанию ExecutersNum = 1. Если выполнение ваших скриптов занимает много времени следует увеличить это значение. Каждый исполнитель скриптов блокируется на время, пока отработает скрипт. Если исполнителей несколько — они принимают скрипты на выполнение по принципу «кто успел».</para></listitem>
- <listitem><para>StgMsgKey – параметр отвечающий за идентификатор очереди сообщений для исполнителя скриптов. По умолчанию данный параметр закомментирован и равен 5555. Рекомендуется не изменять значение параметра без нужды. Его изменение целесообразно лишь в том случае, если в системе требуется запустить более одной копии сервера биллинга.</para></listitem>
- <listitem><para>ShowFeeInCash – показывать на счету и позволять использовать абонплату пользователю. Принимает значения yes и no. Параметр не является обязательным, по умолчанию установлен в yes.</para></listitem>
- <listitem><para>FullFee – снимать полную абонплату, даже если пользователь был заморожен часть учетного периода. Принимает значения yes и no. Параметр не является обязательным, по умолчанию установлен в no.</para></listitem>
- <listitem><para>MessagesTimeout — устанавливает время жизни не отправленных сообщений пользователям. Время указывается в сутках. При превышении этого времени сообщение будет удалено, в т.ч. из БД. Если указан 0 то значения не будут удаляться из базы. По умолчанию 0.</para></listitem>
- <listitem><para>FeeChargeType — регулирует процесс снятия абонплаты. Может принимать значения 0, 1 и 2. При значении 0 абонплата снимается как обычно. При значении 1 абонплата снимается только если баланс пользователя положительный. При значении 2 абонплата снимается только если баланс пользователя больше абонплаты.</para></listitem>
- <listitem><para>ReconnectOnTariffChange — позволяет выполнить переподключение пользователя при смене тарифа. Может принимать значения yes и no. При указании ReconnectOnTariffChange = yes при смене тарифа пользователя если он был подключен произойдет его отключение и подключение заново. Может быть полезно для управления шейпером.</para></listitem>
- <listitem><para>Именования направлений в конфигурационном файле должны быть заключены в теги:
- <programlisting linenumbering="unnumbered">
- <DirNames>
- DirName0 = "ИМЯ НАПРАВЛЕНИЯ"
- ...
- DirName9 = ПОСЛЕДНЕЕ_НАПРАВЛЕНИЕ
- </DirNames>
- </programlisting>
- Всего предусмотрено 10 направлений с нумерацией от 0 до 9. Внутри данных тегов указывается названия направлений. Направления, наименование которых состоит из нескольких слов, должны быть заключены в кавычки. Если наименование направления не указано, то система считает что данное направление не используется и не будет производить по нему никаких действий. Пример: DirName0 = Локаль, DirName5 = "Локальные игры". Необходимо заметить, что текущая версия системы требует, чтобы имена направлений были указаны в кодировке KOI8-R. В противном случае пользователи не смогут их прочитать в статистике авторизатора, а администраторы — в конфигураторе.</para></listitem>
- </itemizedlist>
- <para>Все модули (кроме Store module), которые необходимо подключить к серверу в момент старта должны идти внутри секции:</para>
- <programlisting linenumbering="unnumbered">
- <Modules>
- <Module [имя модуля]>
- ПАРАМЕТРЫ_МОДУЛЯ
- </Module>
- </Modules>
- </programlisting>
- <para>Если модуль не имеет настраиваемых параметров, то он все равно должен задаваться в тегах Module … /Module чтобы быть успешно загруженным. Некоторые модули, такие как store module обязательно требуются при старте и без их подключения система не может быть запущена. По умолчанию для указания конфигурации модулей используются отдельные файлы из каталога conf-enabled.d. Для этого используется директива <IncludeFile ПУТЬ_К_ФАЙЛУ></IncludeFile>. Одна директива указана в секции <Modules>, а вторая в корне файла конфигурации (для store module).</para>
- <formalpara>
- <title>Описание параметров модуля InetAccess (auth_ia) для работы с клиентскими авторизаторами:</title>
- <itemizedlist mark="opencircle">
- <listitem><para>Port – параметр, определяющий на каком порту сервер будет принимать обращения авторизаторов клиентов, по умолчанию UserPort=5555.</para></listitem>
- <listitem><para>UserTimeout – параметр, показывающий серверу, через какое время в секундах клиент будет отключен, если авторизатор не отвечает серверу на запросы. По умолчанию UserTimeout=60. Значение данного параметра должно лежать в диапазоне от 15 до 1200.</para></listitem>
- <listitem><para>UserDelay – время в секундах, через которое сервер опрашивает клиента. Сервер шлет клиенту запрос подтверждения работы авторизатора, а клиент должен прислать ответ что авторизатор находится в рабочем состоянии. Так же это время, через которое у клиента обновляется статистика, по умолчанию UserDelay=5. Следует заметить что значение UserDelay должно быть в 3…10 раз меньше чем значение UserTimeout и данные значения не могут содержать одинаковые таймауты. Значение данного параметра должно лежать в диапазоне от 5 до 600.</para></listitem>
- <listitem>
- <para>FreeMb – параметр, указывающий серверу что будет передаваться авторизатору клиента от сервера. Данный параметр может принимать следующие значения:</para>
- <itemizedlist mark="none">
- <listitem><para>0 - количество бесплатных мегабайт в пересчете на цену нулевого направления;</para></listitem>
- <listitem><para>1 - количество бесплатных мегабайт в пересчете на цену первого направления;</para></listitem>
- <listitem><para>2 - количество бесплатных мегабайт в пересчете на цену второго направления;</para></listitem>
- <listitem><para>...</para></listitem>
- <listitem><para>9 - количество бесплатных мегабайт в пересчете на цену девятого направления;</para></listitem>
- <listitem><para>cash - количество денег на которые клиент может бесплатно работать;</para></listitem>
- <listitem><para>none - ничего не передавать.</para></listitem>
- </itemizedlist>
- </listitem>
- <listitem><para></para></listitem>
- <listitem><para></para></listitem>
- <listitem><para></para></listitem>
- <listitem><para></para></listitem>
- <listitem><para></para></listitem>
- <listitem><para></para></listitem>
- <listitem><para></para></listitem>
- </itemizedlist>
- </formalpara>
- </simplesect>
-</chapter>
+<Module имя_модуля>
+список параметров модуля
+</Module>
+</Modules>
+</programlisting>
+ <para>Если модуль не имеет настраиваемых параметров, то он все равно должен быть указан. Некоторые модули, такие как store module, обязательно требуются при старте и без их подключения система не может быть запущена. По умолчанию для указания конфигурации модулей используются отдельные файлы из каталога conf-enabled.d. Для этого используется директива <IncludeFile ПУТЬ_К_ФАЙЛУ></IncludeFile>. Одна директива указана в секции Modules, а вторая в корне файла конфигурации (для store module).</para>
+ <sect2>
+ <title>Описание параметров модуля InetAccess (auth_ia) для работы с авторизаторами абонентов:</title>
+ <itemizedlist mark="opencircle">
+ <listitem><para>Port – обязательный параметр, определяющий на каком порту сервер будет принимать обращения авторизаторов абонентов. Стандартное значение: 5555.</para></listitem>
+ <listitem><para>UserTimeout – обязательный параметр, указывающий серверу, через какое время в секундах абонент будет отключен если авторизатор не отвечает серверу на запросы. Может принимать значения от 15 до 1200, стандартное значение: 65.</para></listitem>
+ <listitem><para>UserDelay – обязательный параметр, указывающий серверу время в секундах, через которое происходит опрос авторизатора абонента. Сервер шлет абоненту запрос подтверждения работы авторизатора, а авторизатор абонента должен прислать ответ что он находится в рабочем состоянии. Так же это время, через которое в авторизаторе обновляется статистика. Может принимать значения от 5 до 600, стандартное значение: 60. Следует заметить что значение UserDelay должно быть меньше чем значение UserTimeout.</para></listitem>
+ <listitem>
+ <para>FreeMb – обязательный параметр, определяющий в каком виде абоненту будет показано значение FreeMb. Данный параметр может принимать следующие значения:</para>
+ <itemizedlist mark="none">
+ <listitem><para>0 - количество бесплатных мегабайт в пересчете на цену нулевого направления;</para></listitem>
+ <listitem><para>1 - количество бесплатных мегабайт в пересчете на цену первого направления;</para></listitem>
+ <listitem><para>2 - количество бесплатных мегабайт в пересчете на цену второго направления;</para></listitem>
+ <listitem><para>...</para></listitem>
+ <listitem><para>9 - количество бесплатных мегабайт в пересчете на цену девятого направления;</para></listitem>
+ <listitem><para>cash - количество денег на которые клиент может бесплатно работать;</para></listitem>
+ <listitem><para>none - ничего не передавать.</para></listitem>
+ </itemizedlist>
+ </listitem>
+ </itemizedlist>
+ <para>Обмен данными авторизатора с сервером осуществляется по протоколу UDP. Можно указать несколько модулей авторизатора auth_ia для авторизации с разных портов.</para>
+ </sect2>
+ <sect2>
+ <title>Модуль авторизации auth_ao.</title>
+ <para>Модуль параметров не имеет. Используется для поддержки режима Always Online у абонентов. Без включения этого модуля установка параметра alwaysOnline для абонента эффекта иметь не будет. В режиме Always Online абонент находится в авторизованном состоянии все время, независимо от использования авторизатора. Тем не менее он может быть отключен по причине отсутствия средств на счету, заблокирован администратором или «заморожен». В этом режиме так же возможно использование авторизатора за одним исключением — абонент не может сам вызвать «отключение».</para>
+ </sect2>
+ <sect2>
+ <title>Описание параметров модуля SGConfig (conf_sg) для работы с конфигуратором:</title>
+ <itemizedlist mark="opencircle">
+ <listitem><para>Port – обязательный параметр, определяющий, на каком порту сервер будет принимать обращения конфигураторов. Стандартное значение: 5555.</para></listitem>
+ </itemizedlist>
+ <para>Обмен конфигуратора с сервером осуществляется по протоколу TCP. Можно указать несколько модулей конфигуратора с указанием разных портов.</para>
+ </sect2>
+ <sect2>
+ <title>Описание параметров модуля файловой БД:</title>
+ <itemizedlist mark="opencircle">
+ <listitem><para>WorkDir – обязательный параметр, указывающий серверу где находится рабочая директория с файлами БД. Стандартное значение: /var/stargazer.</para></listitem>
+ <listitem><para>ConfOwner, ConfGroup, ConfMode – обязательные параметры, описывающие владельца, группу и права доступа на файлы конфигурации (conf) абонента соответственно. ConfOwner должен содержать корректное имя пользователя системы (см. файл /etc/passwd), стандартное значение: root. ConfGroup должен содержать корректное название группы в системе (см. файл /etc/group), стандарное значение: root. ConfMode должен содержать корректные права на файл (только ugo-биты), стандартное значение: 640.</para></listitem>
+ <listitem><para>StatOwner, StatGroup, StatMode – обязательные параметры, описывающие владельца, группу и права доступа на файлы статистики (stat) абонента соответственно. StatOwner должен содержать корректное имя пользователя системы (см. файл /etc/passwd), стандартное значение: root. StatGroup должен содержать корректное название группы в системе (см. файл /etc/group), стандарное значение: root. StatMode должен содержать корректные права на файл (только ugo-биты), стандартное значение: 640.</para></listitem>
+ <listitem><para>UserLogOwner, UserLogGroup, UserLogMode – обязательные параметры, описывающие владельца, группу и права доступа на файлы журналов (log) абонента соответственно. UserLogOwner должен содержать корректное имя пользователя системы (см. файл /etc/passwd), стандартное значение: root. UserLogGroup должен содержать корректное название группы в системе (см. файл /etc/group), стандарное значение: root. UserLogMode должен содержать корректные права на файл (только ugo-биты), стандартное значение: 640.</para></listitem>
+ </itemizedlist>
+ <para>При создании каталогов (например для записи детальной статистики) используются те-же права, но с добавлением x-бита для всех ненулевых полей. Например: для 640 будут права 750, а для 644 будут 755. Для записи детальной статистики используются параметры StatOwner, StatGroup и StatMode. Для записи сообщений используются параметры ConfOwner, ConfGroup и ConfMode.</para>
+ </sect2>
+ </chapter>
+ <para></para>
\ No newline at end of file
<para>Логин администратора</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term>string <parameter>password</parameter></term>
+ <listitem>
+ <para>Пароль администратора</para>
+ </listitem>
+ </varlistentry>
<varlistentry>
<term>boolean <parameter>user_stat</parameter></term>
<listitem>
stg/auth.h \
stg/const.h \
stg/corp_conf.h \
+ stg/corporations.h \
stg/ia_packets.h \
stg/message.h \
stg/module_settings.h \
stg/notifer.h \
stg/os_int.h \
stg/plugin.h \
+ stg/plugin_creator.h \
stg/rad_packets.h \
stg/raw_ip_packet.h \
stg/resetable.h \
stg/rs_packets.h \
stg/service_conf.h \
+ stg/services.h \
stg/settings.h \
stg/store.h \
stg/tariff_conf.h \
class ADMIN {
public:
- virtual ADMIN & operator=(const ADMIN &) = 0;
- virtual ADMIN & operator=(const ADMIN_CONF &) = 0;
- virtual bool operator==(const ADMIN & rhs) const = 0;
- virtual bool operator!=(const ADMIN & rhs) const = 0;
- virtual bool operator<(const ADMIN & rhs) const = 0;
- virtual bool operator<=(const ADMIN & rhs) const = 0;
-
- virtual const std::string & GetPassword() const = 0;
- virtual const std::string & GetLogin() const = 0;
- virtual PRIV const * GetPriv() const = 0;
- virtual uint16_t GetPrivAsInt() const = 0;
- virtual const ADMIN_CONF & GetConf() const = 0;
- virtual uint32_t GetIP() const = 0;
- virtual std::string GetIPStr() const = 0;
- virtual void SetIP(uint32_t ip) = 0;
- virtual const std::string GetLogStr() const = 0;
+ virtual ~ADMIN() {}
+ virtual const std::string & GetPassword() const = 0;
+ virtual const std::string & GetLogin() const = 0;
+ virtual PRIV const * GetPriv() const = 0;
+ virtual uint16_t GetPrivAsInt() const = 0;
+ virtual const ADMIN_CONF & GetConf() const = 0;
+ virtual uint32_t GetIP() const = 0;
+ virtual std::string GetIPStr() const = 0;
+ virtual void SetIP(uint32_t ip) = 0;
+ virtual const std::string GetLogStr() const = 0;
};
#endif
userPasswd(0),
userAddDel(0),
adminChg(0),
- tariffChg(0)
- {};
- PRIV(uint16_t p)
- : userStat((p & 0x0003) >> 0x00),
- userConf((p & 0x000C) >> 0x02),
- userCash((p & 0x0030) >> 0x04),
- userPasswd((p & 0x00C0) >> 0x06),
- userAddDel((p & 0x0300) >> 0x08),
- adminChg((p & 0x0C00) >> 0x0A),
- tariffChg((p & 0x3000) >> 0x0C)
+ tariffChg(0),
+ serviceChg(0),
+ corpChg(0)
+ {}
+ PRIV(uint32_t p)
+ : userStat((p & 0x00000003) >> 0x00),
+ userConf((p & 0x0000000C) >> 0x02),
+ userCash((p & 0x00000030) >> 0x04),
+ userPasswd((p & 0x000000C0) >> 0x06),
+ userAddDel((p & 0x00000300) >> 0x08),
+ adminChg((p & 0x00000C00) >> 0x0A),
+ tariffChg((p & 0x00003000) >> 0x0C),
+ serviceChg((p & 0x0000C000) >> 0x0E),
+ corpChg((p & 0x00030000) >> 0x10)
{}
- uint16_t ToInt() const;
- void FromInt(uint16_t p);
+ uint32_t ToInt() const;
+ void FromInt(uint32_t p);
uint16_t userStat;
uint16_t userConf;
uint16_t userAddDel;
uint16_t adminChg;
uint16_t tariffChg;
+ uint16_t serviceChg;
+ uint16_t corpChg;
};
//-----------------------------------------------------------------------------
struct ADMIN_CONF
#define ADMIN_CONF_INC_H
inline
-uint16_t PRIV::ToInt() const
+uint32_t PRIV::ToInt() const
{
-uint16_t p = (userStat << 0) |
+uint32_t p = (userStat << 0) |
(userConf << 2) |
(userCash << 4) |
(userPasswd << 6) |
(userAddDel << 8) |
(adminChg << 10) |
- (tariffChg << 12);
+ (tariffChg << 12) |
+ (serviceChg << 14) |
+ (corpChg << 16);
return p;
}
inline
-void PRIV::FromInt(uint16_t p)
+void PRIV::FromInt(uint32_t p)
{
-userStat = (p & 0x0003) >> 0x00; // 1+2
-userConf = (p & 0x000C) >> 0x02; // 4+8
-userCash = (p & 0x0030) >> 0x04; // 10+20
-userPasswd = (p & 0x00C0) >> 0x06; // 40+80
-userAddDel = (p & 0x0300) >> 0x08; // 100+200
-adminChg = (p & 0x0C00) >> 0x0A; // 400+800
-tariffChg = (p & 0x3000) >> 0x0C; // 1000+2000
+userStat = (p & 0x00000003) >> 0x00; // 1+2
+userConf = (p & 0x0000000C) >> 0x02; // 4+8
+userCash = (p & 0x00000030) >> 0x04; // 10+20
+userPasswd = (p & 0x000000C0) >> 0x06; // 40+80
+userAddDel = (p & 0x00000300) >> 0x08; // 100+200
+adminChg = (p & 0x00000C00) >> 0x0A; // 400+800
+tariffChg = (p & 0x00003000) >> 0x0C; // 1000+2000
+serviceChg = (p & 0x0000C000) >> 0x0E; // 4000+8000
+corpChg = (p & 0x00030000) >> 0x10; // 10000+20000
}
#endif
class ADMINS {
public:
+ virtual ~ADMINS() {}
virtual int Add(const std::string & login, const ADMIN * admin) = 0;
virtual int Del(const std::string & login, const ADMIN * admin) = 0;
virtual int Change(const ADMIN_CONF & ac, const ADMIN * admin) = 0;
virtual const ADMIN * GetSysAdmin() const = 0;
virtual const ADMIN * GetNoAdmin() const = 0;
- virtual bool FindAdmin(const std::string & l, ADMIN ** admin) = 0;
- virtual bool AdminExists(const std::string & login) const = 0;
- virtual bool AdminCorrect(const std::string & login,
- const std::string & password,
- ADMIN ** admin) = 0;
+ virtual bool Find(const std::string & l, ADMIN ** admin) = 0;
+ virtual bool Exists(const std::string & login) const = 0;
+ virtual bool Correct(const std::string & login,
+ const std::string & password,
+ ADMIN ** admin) = 0;
virtual const std::string & GetStrError() const = 0;
+ virtual size_t Count() const = 0;
virtual int OpenSearch() const = 0;
virtual int SearchNext(int, ADMIN_CONF * ac) const = 0;
#ifndef CORP_CONF_H
#define CORP_CONF_H
+#include <string>
+
struct CORP_CONF
{
-string name;
-double cash;
+CORP_CONF() : name(), cash(0) {}
+CORP_CONF(const std::string & n) : name(n), cash(0) {}
+CORP_CONF(const std::string & n, double c) : name(n), cash(c) {}
+
+std::string name;
+double cash;
};
+inline
+bool operator==(const CORP_CONF & a, const CORP_CONF & b)
+{
+return a.name == b.name;
+}
+
#endif //CORP_CONF_H
--- /dev/null
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Author : Maxim Mamontov <faust@stargazer.dp.ua>
+ */
+
+#ifndef CORPORATIONS_H
+#define CORPORATIONS_H
+
+#include <string>
+
+#include "corp_conf.h"
+
+class ADMIN;
+
+class CORPORATIONS {
+public:
+ virtual ~CORPORATIONS() {}
+ virtual int Add(const CORP_CONF & corp, const ADMIN * admin) = 0;
+ virtual int Del(const std::string & name, const ADMIN * admin) = 0;
+ virtual int Change(const CORP_CONF & corp, const ADMIN * admin) = 0;
+ virtual bool Find(const std::string & name, CORP_CONF * corp) = 0;
+ virtual bool Exists(const std::string & name) const = 0;
+ virtual const std::string & GetStrError() const = 0;
+ virtual size_t Count() const = 0;
+
+ virtual int OpenSearch() const = 0;
+ virtual int SearchNext(int, CORP_CONF * corp) const = 0;
+ virtual int CloseSearch(int) const = 0;
+};
+
+#endif
showTime(0),
repeat(0),
repeatPeriod(0)
-{};
+{}
uint64_t id;
unsigned ver;
//-----------------------------------------------------------------------------
struct STG_MSG
{
-STG_MSG() {};
+STG_MSG() : header(), text() {}
time_t GetNextSendTime() const
{
return header.lastSendTime + header.repeat * 60;
-};
+}
STG_MSG_HDR header;
std::string text;
#include "admins.h"
#include "users.h"
#include "tariffs.h"
+#include "services.h"
+#include "corporations.h"
class TRAFFCOUNTER;
class SETTINGS;
class PLUGIN : private NONCOPYABLE {
public:
- virtual void SetUsers(USERS * u) = 0;
- virtual void SetTariffs(TARIFFS * t) = 0;
- virtual void SetAdmins(ADMINS * a) = 0;
- virtual void SetTraffcounter(TRAFFCOUNTER * tc) = 0;
- virtual void SetStore(STORE * st) = 0;
- virtual void SetStgSettings(const SETTINGS * s) = 0;
- virtual void SetSettings(const MODULE_SETTINGS & s) = 0;
+ virtual ~PLUGIN() {}
+ virtual void SetUsers(USERS *) {}
+ virtual void SetTariffs(TARIFFS *) {}
+ virtual void SetAdmins(ADMINS *) {}
+ virtual void SetServices(SERVICES *) {}
+ virtual void SetCorporations(CORPORATIONS *) {}
+ virtual void SetTraffcounter(TRAFFCOUNTER *) {}
+ virtual void SetStore(STORE *) {}
+ virtual void SetStgSettings(const SETTINGS *) {}
+ virtual void SetSettings(const MODULE_SETTINGS &) {}
virtual int ParseSettings() = 0;
virtual int Start() = 0;
--- /dev/null
+#ifndef __PLUGIN_CREATOR_H__
+#define __PLUGIN_CREATOR_H__
+
+template <class T>
+class PLUGIN_CREATOR
+{
+public:
+ PLUGIN_CREATOR() : plugin(new T()) {}
+ ~PLUGIN_CREATOR() { delete plugin; }
+
+ T * GetPlugin() { return plugin; }
+
+private:
+ T * plugin;
+
+ PLUGIN_CREATOR(const PLUGIN_CREATOR<T> & rvalue);
+ PLUGIN_CREATOR<T> & operator=(const PLUGIN_CREATOR<T> & rvalue);
+};
+
+#endif
#include <cstring>
-#include "const.h"
-#include "common.h"
-
#define IPv4 (2)
enum { pcktSize = 68 }; //60(max) ip + 8 udp or tcp (part of tcp or udp header to ports)
struct RAW_PACKET
{
RAW_PACKET()
- : dataLen(-1)
+ : rawPacket(),
+ dataLen(-1)
{
- memset(pckt, 0, pcktSize);
+ memset(rawPacket.pckt, 0, pcktSize);
}
RAW_PACKET(const RAW_PACKET & rp)
- : dataLen(rp.dataLen)
+ : rawPacket(),
+ dataLen(rp.dataLen)
{
- memcpy(pckt, rp.pckt, pcktSize);
+ memcpy(rawPacket.pckt, rp.rawPacket.pckt, pcktSize);
}
uint16_t GetIPVersion() const;
uint16_t sPort;
uint16_t dPort;
} header __attribute__ ((packed));
- };
+ } rawPacket;
int32_t dataLen; // IP packet length. Set to -1 to use length field from the header
};
//-----------------------------------------------------------------------------
inline uint16_t RAW_PACKET::GetIPVersion() const
{
-return header.ipHeader.ip_v;
+return rawPacket.header.ipHeader.ip_v;
}
//-----------------------------------------------------------------------------
inline uint8_t RAW_PACKET::GetHeaderLen() const
{
-return header.ipHeader.ip_hl * 4;
+return rawPacket.header.ipHeader.ip_hl * 4;
}
//-----------------------------------------------------------------------------
inline uint8_t RAW_PACKET::GetProto() const
{
-return header.ipHeader.ip_p;
+return rawPacket.header.ipHeader.ip_p;
}
//-----------------------------------------------------------------------------
inline uint32_t RAW_PACKET::GetLen() const
{
if (dataLen != -1)
return dataLen;
-return ntohs(header.ipHeader.ip_len);
+return ntohs(rawPacket.header.ipHeader.ip_len);
}
//-----------------------------------------------------------------------------
inline uint32_t RAW_PACKET::GetSrcIP() const
{
-return header.ipHeader.ip_src.s_addr;
+return rawPacket.header.ipHeader.ip_src.s_addr;
}
//-----------------------------------------------------------------------------
inline uint32_t RAW_PACKET::GetDstIP() const
{
-return header.ipHeader.ip_dst.s_addr;
+return rawPacket.header.ipHeader.ip_dst.s_addr;
}
//-----------------------------------------------------------------------------
inline uint16_t RAW_PACKET::GetSrcPort() const
{
-if (header.ipHeader.ip_p == 1) // for icmp proto return port 0
+if (rawPacket.header.ipHeader.ip_p == 1) // for icmp proto return port 0
return 0;
-return ntohs(*((uint16_t*)(pckt + header.ipHeader.ip_hl * 4)));
+return ntohs(*((uint16_t*)(rawPacket.pckt + rawPacket.header.ipHeader.ip_hl * 4)));
}
//-----------------------------------------------------------------------------
inline uint16_t RAW_PACKET::GetDstPort() const
{
-if (header.ipHeader.ip_p == 1) // for icmp proto return port 0
+if (rawPacket.header.ipHeader.ip_p == 1) // for icmp proto return port 0
return 0;
-return ntohs(*((uint16_t*)(pckt + header.ipHeader.ip_hl * 4 + 2)));
+return ntohs(*((uint16_t*)(rawPacket.pckt + rawPacket.header.ipHeader.ip_hl * 4 + 2)));
}
//-----------------------------------------------------------------------------
inline bool RAW_PACKET::operator==(const RAW_PACKET & rvalue) const
{
-if (header.ipHeader.ip_src.s_addr != rvalue.header.ipHeader.ip_src.s_addr)
+if (rawPacket.header.ipHeader.ip_src.s_addr != rvalue.rawPacket.header.ipHeader.ip_src.s_addr)
return false;
-if (header.ipHeader.ip_dst.s_addr != rvalue.header.ipHeader.ip_dst.s_addr)
+if (rawPacket.header.ipHeader.ip_dst.s_addr != rvalue.rawPacket.header.ipHeader.ip_dst.s_addr)
return false;
-if (header.ipHeader.ip_p != 1 && rvalue.header.ipHeader.ip_p != 1)
+if (rawPacket.header.ipHeader.ip_p != 1 && rvalue.rawPacket.header.ipHeader.ip_p != 1)
{
- if (*((uint16_t *)(pckt + header.ipHeader.ip_hl * 4)) !=
- *((uint16_t *)(rvalue.pckt + rvalue.header.ipHeader.ip_hl * 4)))
+ if (*((uint16_t *)(rawPacket.pckt + rawPacket.header.ipHeader.ip_hl * 4)) !=
+ *((uint16_t *)(rvalue.rawPacket.pckt + rvalue.rawPacket.header.ipHeader.ip_hl * 4)))
return false;
- if (*((uint16_t *)(pckt + header.ipHeader.ip_hl * 4 + 2)) !=
- *((uint16_t *)(rvalue.pckt + rvalue.header.ipHeader.ip_hl * 4 + 2)))
+ if (*((uint16_t *)(rawPacket.pckt + rawPacket.header.ipHeader.ip_hl * 4 + 2)) !=
+ *((uint16_t *)(rvalue.rawPacket.pckt + rvalue.rawPacket.header.ipHeader.ip_hl * 4 + 2)))
return false;
}
-if (header.ipHeader.ip_p != rvalue.header.ipHeader.ip_p)
+if (rawPacket.header.ipHeader.ip_p != rvalue.rawPacket.header.ipHeader.ip_p)
return false;
return true;
//-----------------------------------------------------------------------------
inline bool RAW_PACKET::operator<(const RAW_PACKET & rvalue) const
{
-if (header.ipHeader.ip_src.s_addr < rvalue.header.ipHeader.ip_src.s_addr)
+if (rawPacket.header.ipHeader.ip_src.s_addr < rvalue.rawPacket.header.ipHeader.ip_src.s_addr)
return true;
-if (header.ipHeader.ip_src.s_addr > rvalue.header.ipHeader.ip_src.s_addr)
+if (rawPacket.header.ipHeader.ip_src.s_addr > rvalue.rawPacket.header.ipHeader.ip_src.s_addr)
return false;
-if (header.ipHeader.ip_dst.s_addr < rvalue.header.ipHeader.ip_dst.s_addr)
+if (rawPacket.header.ipHeader.ip_dst.s_addr < rvalue.rawPacket.header.ipHeader.ip_dst.s_addr)
return true;
-if (header.ipHeader.ip_dst.s_addr > rvalue.header.ipHeader.ip_dst.s_addr)
+if (rawPacket.header.ipHeader.ip_dst.s_addr > rvalue.rawPacket.header.ipHeader.ip_dst.s_addr)
return false;
-if (header.ipHeader.ip_p != 1 && rvalue.header.ipHeader.ip_p != 1)
+if (rawPacket.header.ipHeader.ip_p != 1 && rvalue.rawPacket.header.ipHeader.ip_p != 1)
{
- if (*((uint16_t *)(pckt + header.ipHeader.ip_hl * 4)) <
- *((uint16_t *)(rvalue.pckt + rvalue.header.ipHeader.ip_hl * 4)))
+ if (*((uint16_t *)(rawPacket.pckt + rawPacket.header.ipHeader.ip_hl * 4)) <
+ *((uint16_t *)(rvalue.rawPacket.pckt + rvalue.rawPacket.header.ipHeader.ip_hl * 4)))
return true;
- if (*((uint16_t *)(pckt + header.ipHeader.ip_hl * 4)) >
- *((uint16_t *)(rvalue.pckt + rvalue.header.ipHeader.ip_hl * 4)))
+ if (*((uint16_t *)(rawPacket.pckt + rawPacket.header.ipHeader.ip_hl * 4)) >
+ *((uint16_t *)(rvalue.rawPacket.pckt + rvalue.rawPacket.header.ipHeader.ip_hl * 4)))
return false;
- if (*((uint16_t *)(pckt + header.ipHeader.ip_hl * 4 + 2)) <
- *((uint16_t *)(rvalue.pckt + rvalue.header.ipHeader.ip_hl * 4 + 2)))
+ if (*((uint16_t *)(rawPacket.pckt + rawPacket.header.ipHeader.ip_hl * 4 + 2)) <
+ *((uint16_t *)(rvalue.rawPacket.pckt + rvalue.rawPacket.header.ipHeader.ip_hl * 4 + 2)))
return true;
- if (*((uint16_t *)(pckt + header.ipHeader.ip_hl * 4 + 2)) >
- *((uint16_t *)(rvalue.pckt + rvalue.header.ipHeader.ip_hl * 4 + 2)))
+ if (*((uint16_t *)(rawPacket.pckt + rawPacket.header.ipHeader.ip_hl * 4 + 2)) >
+ *((uint16_t *)(rvalue.rawPacket.pckt + rvalue.rawPacket.header.ipHeader.ip_hl * 4 + 2)))
return false;
}
-if (header.ipHeader.ip_p < rvalue.header.ipHeader.ip_p)
+if (rawPacket.header.ipHeader.ip_p < rvalue.rawPacket.header.ipHeader.ip_p)
return true;
return false;
#include <iostream>
-template <typename varT>
+template <typename T>
class RESETABLE
{
- template <typename varT1>
- friend std::ostream & operator<<(std::ostream & o, RESETABLE<varT1> v);
public:
- typedef varT value_type;
+ typedef T value_type;
- //-------------------------------------------------------------------------
- RESETABLE()
- : value(),
- is_set(false)
- {
- }
- //-------------------------------------------------------------------------
- RESETABLE<value_type>(const RESETABLE<value_type> & rvalue)
+ RESETABLE() : value(), is_set(false) {}
+
+ RESETABLE(const RESETABLE<value_type> & rvalue)
: value(rvalue.value),
is_set(rvalue.is_set)
- {
- }
- //-------------------------------------------------------------------------
- RESETABLE(const value_type& val)
- : value(val),
- is_set(true)
- {
- }
- //-------------------------------------------------------------------------
+ {}
+
+ RESETABLE(const value_type& val) : value(val), is_set(true) {}
+
RESETABLE<value_type> & operator=(const RESETABLE<value_type> & rvalue)
{
value = rvalue.value;
is_set = rvalue.is_set;
return *this;
}
- //-------------------------------------------------------------------------
- RESETABLE<value_type> & operator= (const value_type& rhs)
+
+ RESETABLE<value_type> & operator=(const value_type& rhs)
{
value = rhs;
is_set = true;
return *this;
}
- //-------------------------------------------------------------------------
- const value_type& const_data() const throw()
- {
- return value;
- }
- //-------------------------------------------------------------------------
- value_type& data() throw()
- {
- return value;
- }
- //-------------------------------------------------------------------------
- operator const value_type&() const throw()
- {
- return value;
- }
- //-------------------------------------------------------------------------
- bool res_empty() const throw()
- {
- return !is_set;
- }
- //-------------------------------------------------------------------------
- void reset() throw()
- {
- is_set = false;
- }
- //-------------------------------------------------------------------------
-protected:
- value_type value;
- bool is_set;
+
+ const value_type & const_data() const throw() { return value; }
+ value_type & data() throw() { return value; }
+ operator const value_type&() const throw() { return value; }
+ bool res_empty() const throw() { return !is_set; }
+ void reset() throw() { is_set = false; }
+
+private:
+ value_type value;
+ bool is_set;
};
-//-----------------------------------------------------------------------------
-template <typename varT>
-std::ostream & operator<<(std::ostream & o, RESETABLE<varT> v)
+
+template <typename T>
+std::ostream & operator<<(std::ostream & o, const RESETABLE<T> & v);
+
+template <typename T>
+inline
+std::ostream & operator<<(std::ostream & o, const RESETABLE<T> & v)
{
- return o << v.value;
+ return o << v.const_data();
}
-//-------------------------------------------------------------------------
-#endif // RESETABLE_VARIABLE_H
+#endif // RESETABLE_VARIABLE_H
#ifndef SERVICE_CONF_H
#define SERVICE_CONF_H
+#include <string>
+
+#include "os_int.h"
+
struct SERVICE_CONF
{
-string name;
-string comment;
-double cost;
-int payDay;
+SERVICE_CONF()
+ : name(), comment(), cost(0), payDay(0)
+{}
+SERVICE_CONF(const std::string & n)
+ : name(n), comment(), cost(0), payDay(0)
+{}
+SERVICE_CONF(const std::string & n, double c)
+ : name(n), comment(), cost(c), payDay(0)
+{}
+SERVICE_CONF(const std::string & n, double c, unsigned p)
+ : name(n), comment(), cost(c), payDay(p)
+{}
+SERVICE_CONF(const std::string & n, double c,
+ unsigned p, const std::string & com)
+ : name(n), comment(com), cost(c), payDay(p)
+{}
+
+std::string name;
+std::string comment;
+double cost;
+uint8_t payDay;
};
+inline
+bool operator==(const SERVICE_CONF & a, const SERVICE_CONF & b)
+{
+return a.name == b.name;
+}
+
#endif //SERVICE_CONF_H
--- /dev/null
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Author : Maxim Mamontov <faust@stargazer.dp.ua>
+ */
+
+#ifndef SERVICES_H
+#define SERVICES_H
+
+#include <string>
+
+#include "service_conf.h"
+
+class ADMIN;
+
+class SERVICES {
+public:
+ virtual ~SERVICES() {}
+ virtual int Add(const SERVICE_CONF & service, const ADMIN * admin) = 0;
+ virtual int Del(const std::string & name, const ADMIN * admin) = 0;
+ virtual int Change(const SERVICE_CONF & service, const ADMIN * admin) = 0;
+ virtual bool Find(const std::string & name, SERVICE_CONF * service) = 0;
+ virtual bool Exists(const std::string & name) const = 0;
+ virtual const std::string & GetStrError() const = 0;
+ virtual size_t Count() const = 0;
+
+ virtual int OpenSearch() const = 0;
+ virtual int SearchNext(int, SERVICE_CONF * service) const = 0;
+ virtual int CloseSearch(int) const = 0;
+};
+
+#endif
class SETTINGS {
public:
+ virtual ~SETTINGS() {}
virtual const std::string & GetDirName(size_t num) const = 0;
virtual const std::string & GetScriptsDir() const = 0;
virtual unsigned GetDetailStatWritePeriod() const = 0;
//-----------------------------------------------------------------------------
class STORE {
public:
+ virtual ~STORE() {}
virtual int GetUsersList(std::vector<std::string> * usersList) const = 0;
virtual int AddUser(const std::string & login) const = 0;
virtual int DelUser(const std::string & login) const = 0;
class TARIFF {
public:
+ virtual ~TARIFF() {}
virtual double GetPriceWithTraffType(uint64_t up,
uint64_t down,
int dir,
virtual int64_t GetTraffByType(uint64_t up, uint64_t down) const = 0;
virtual int GetThreshold(int dir) const = 0;
virtual const TARIFF_DATA & GetTariffData() const = 0;
-
- virtual TARIFF & operator=(const TARIFF_DATA & td) = 0;
- virtual TARIFF & operator=(const TARIFF & t) = 0;
- virtual bool operator==(const TARIFF & rhs) const = 0;
- virtual bool operator!=(const TARIFF & rhs) const = 0;
};
#endif
singlePrice(0),
noDiscount(0)
{}
- int hDay;
- int mDay;
- int hNight;
- int mNight;
- double priceDayA;
- double priceNightA;
- double priceDayB;
- double priceNightB;
- int threshold;
- int singlePrice; // Do not use day/night division
- int noDiscount; // Do not use threshold
+ int hDay;
+ int mDay;
+ int hNight;
+ int mNight;
+ double priceDayA;
+ double priceNightA;
+ double priceDayB;
+ double priceNightB;
+ int threshold;
+ int singlePrice; // Do not use day/night division
+ int noDiscount; // Do not use threshold
};
//-----------------------------------------------------------------------------
struct DIRPRICE_DATA_RES
{
- DIRPRICE_DATA_RES & operator= (const DIRPRICE_DATA & dpd)
+ DIRPRICE_DATA_RES()
+ : hDay(),
+ mDay(),
+ hNight(),
+ mNight(),
+ priceDayA(),
+ priceNightA(),
+ priceDayB(),
+ priceNightB(),
+ threshold(),
+ singlePrice(),
+ noDiscount()
+ {}
+
+ DIRPRICE_DATA_RES & operator= (const DIRPRICE_DATA & rvalue)
{
- hDay = dpd.hDay;
- mDay = dpd.mDay;
- hNight = dpd.hNight;
- mNight = dpd.mNight;
- priceDayA = dpd.priceDayA;
- priceNightA = dpd.priceNightA;
- priceDayB = dpd.priceDayB;
- priceNightB = dpd.priceNightB;
- threshold = dpd.threshold;
- singlePrice = dpd.singlePrice;
- noDiscount = dpd.noDiscount;
+ hDay = rvalue.hDay;
+ mDay = rvalue.mDay;
+ hNight = rvalue.hNight;
+ mNight = rvalue.mNight;
+ priceDayA = rvalue.priceDayA;
+ priceNightA = rvalue.priceNightA;
+ priceDayB = rvalue.priceDayB;
+ priceNightB = rvalue.priceNightB;
+ threshold = rvalue.threshold;
+ singlePrice = rvalue.singlePrice;
+ noDiscount = rvalue.noDiscount;
return *this;
- };
+ }
DIRPRICE_DATA GetData()
{
return dd;
}
- RESETABLE<int> hDay;
- RESETABLE<int> mDay;
- RESETABLE<int> hNight;
- RESETABLE<int> mNight;
- RESETABLE<double> priceDayA;
- RESETABLE<double> priceNightA;
- RESETABLE<double> priceDayB;
- RESETABLE<double> priceNightB;
- RESETABLE<int> threshold;
- RESETABLE<int> singlePrice;
- RESETABLE<int> noDiscount;
+ RESETABLE<int> hDay;
+ RESETABLE<int> mDay;
+ RESETABLE<int> hNight;
+ RESETABLE<int> mNight;
+ RESETABLE<double> priceDayA;
+ RESETABLE<double> priceNightA;
+ RESETABLE<double> priceDayB;
+ RESETABLE<double> priceNightB;
+ RESETABLE<int> threshold;
+ RESETABLE<int> singlePrice;
+ RESETABLE<int> noDiscount;
};
//-----------------------------------------------------------------------------
struct TARIFF_CONF
{
- double fee; // ÷ÅÌÉÞÉÎÁ ÁÂÏÎÐÌÁÔÙ
- double free; // îÁ ËÁËÕÀ ÓÕÍÍÕ ÄÅÎÅÇ ÀÚÅÒ ËÁÞÁÅÔ ÂÅÓÐÌÁÔÎÏ
- int traffType; // UP, DOWN, UP+DOWN, MAX
- double passiveCost; // óÔÏÉÍÏÓÔØ ÚÁÍÏÒÏÚËÉ
+ double fee;
+ double free;
+ int traffType;
+ double passiveCost;
std::string name;
TARIFF_CONF()
: fee(0),
free(0),
- traffType(TRAFF_UP_DOWN), // UP-DOWN
+ traffType(TRAFF_UP_DOWN),
passiveCost(0),
name()
- {};
+ {}
TARIFF_CONF(const std::string & n)
: fee(0),
free(0),
- traffType(TRAFF_UP_DOWN), // UP-DOWN
+ traffType(TRAFF_UP_DOWN),
passiveCost(0),
name(n)
- {};
+ {}
};
//-----------------------------------------------------------------------------
struct TARIFF_CONF_RES
{
+ TARIFF_CONF_RES()
+ : fee(),
+ free(),
+ traffType(),
+ passiveCost(),
+ name()
+ {}
+
TARIFF_CONF_RES & operator=(const TARIFF_CONF & tc)
{
fee = tc.fee;
passiveCost = tc.passiveCost;
name = tc.name;
return *this;
- };
+ }
TARIFF_CONF GetData()
{
return tc;
}
- RESETABLE<double> fee;
- RESETABLE<double> free;
- RESETABLE<int> traffType;
- RESETABLE<double> passiveCost;
- RESETABLE<std::string> name;
+ RESETABLE<double> fee;
+ RESETABLE<double> free;
+ RESETABLE<int> traffType;
+ RESETABLE<double> passiveCost;
+ RESETABLE<std::string> name;
};
//-----------------------------------------------------------------------------
struct TARIFF_DATA
{
- TARIFF_CONF tariffConf;
- std::vector<DIRPRICE_DATA> dirPrice;
+ TARIFF_CONF tariffConf;
+ std::vector<DIRPRICE_DATA> dirPrice;
TARIFF_DATA()
: tariffConf(),
tariffConf = td.tariffConf;
dirPrice = td.dirPrice;
return *this;
- };
+ }
};
//-----------------------------------------------------------------------------
struct TARIFF_DATA_RES
{
- TARIFF_CONF_RES tariffConf;
+ TARIFF_CONF_RES tariffConf;
std::vector<DIRPRICE_DATA_RES> dirPrice;
TARIFF_DATA_RES()
{
TARIFF_DATA td;
td.tariffConf = tariffConf.GetData();
- for (int i = 0; i < DIR_NUM; i++)
+ for (size_t i = 0; i < DIR_NUM; i++)
td.dirPrice[i] = dirPrice[i].GetData();
return td;
}
#include <string>
#include <list>
+#include "notifer.h"
+
class ADMIN;
class TARIFF;
struct TARIFF_DATA;
class TARIFFS {
public:
- virtual int ReadTariffs () = 0;
+ virtual ~TARIFFS() {}
+ virtual int ReadTariffs () = 0;
virtual const TARIFF * FindByName(const std::string & name) const = 0;
virtual const TARIFF * GetNoTariff() const = 0;
- virtual int GetTariffsNum() const = 0;
- virtual int Del(const std::string & name, const ADMIN * admin) = 0;
- virtual int Add(const std::string & name, const ADMIN * admin) = 0;
- virtual int Chg(const TARIFF_DATA & td, const ADMIN * admin) = 0;
+ virtual int Del(const std::string & name, const ADMIN * admin) = 0;
+ virtual int Add(const std::string & name, const ADMIN * admin) = 0;
+ virtual int Chg(const TARIFF_DATA & td, const ADMIN * admin) = 0;
+
+ virtual void AddNotifierAdd(NOTIFIER_BASE<TARIFF_DATA> * notifier) = 0;
+ virtual void DelNotifierAdd(NOTIFIER_BASE<TARIFF_DATA> * notifier) = 0;
+
+ virtual void AddNotifierDel(NOTIFIER_BASE<TARIFF_DATA> * notifier) = 0;
+ virtual void DelNotifierDel(NOTIFIER_BASE<TARIFF_DATA> * notifier) = 0;
+
+ virtual void GetTariffsData(std::list<TARIFF_DATA> * tdl) = 0;
- virtual void GetTariffsData(std::list<TARIFF_DATA> * tdl) = 0;
+ virtual size_t Count() const = 0;
virtual const std::string & GetStrError() const = 0;
};
class TRAFFCOUNTER {
public:
+ virtual ~TRAFFCOUNTER() {}
virtual void Process(const RAW_PACKET & rawPacket) = 0;
+ virtual size_t RulesCount() const = 0;
};
#endif
class USER {
public:
+ virtual ~USER() {}
virtual int WriteConf() = 0;
virtual int WriteStat() = 0;
virtual bool GetConnected() const = 0;
virtual time_t GetConnectedModificationTime() const = 0;
virtual int GetAuthorized() const = 0;
- virtual int Authorize(uint32_t ip,
+ /*virtual int Authorize(uint32_t ip,
uint32_t enabledDirs,
const AUTH * auth) = 0;
- virtual void Unauthorize(const AUTH * auth) = 0;
+ virtual void Unauthorize(const AUTH * auth) = 0;*/
virtual bool IsAuthorizedBy(const AUTH * auth) const = 0;
virtual int AddMessage(STG_MSG * msg) = 0;
};
typedef USER * USER_PTR;
+typedef const USER * CONST_USER_PTR;
#endif
#include <iostream>
#include <sstream>
-#include "common.h"
+#include "stg/common.h"
#include "os_int.h"
using namespace std;
}
//-----------------------------------------------------------------------------
inline
+uint32_t USER_IPS::CalcMask(unsigned int msk) const
+{
+if (msk > 32)
+ return 0;
+return htonl(0xFFffFFff << (32 - msk));
+}
+//-----------------------------------------------------------------------------
+inline
bool USER_IPS::IsIPInIPS(uint32_t ip) const
{
if (ips.empty())
}
//-----------------------------------------------------------------------------
inline
-uint32_t USER_IPS::CalcMask(unsigned int msk) const
-{
-if (msk > 32)
- return 0;
-return htonl(0xFFffFFff << (32 - msk));
-}
-//-----------------------------------------------------------------------------
-inline
void USER_IPS::Add(const IP_MASK &im)
{
ips.push_back(im);
#include <sstream>
#include <iostream>
+#include "stg/logger.h"
+#include "stg/locker.h"
+#include "stg/scriptexecuter.h"
+
#include "store.h"
#include "admin.h"
#include "notifer.h"
-#include "logger.h"
-#include "locker.h"
-#include "scriptexecuter.h"
#include "noncopyable.h"
extern const volatile time_t stgTime;
inline
USER_PROPERTY<varT>::USER_PROPERTY(varT & val)
: value(val),
- modificationTime(stgTime)
+ modificationTime(stgTime),
+ beforeNotifiers(),
+ afterNotifiers(),
+ mutex()
{
pthread_mutex_init(&mutex, NULL);
}
if (access(filePath.c_str(), X_OK) == 0)
{
std::string execString("\"" + filePath + "\" \"" + login + "\" \"" + paramName + "\" \"" + oldValue + "\" \"" + newValue + "\" \"" + admin->GetLogin() + "\" \"" + admin->GetIPStr() + "\"");
- ScriptExec(execString);
+ ScriptExec(execString.c_str());
}
else
{
{
traff = ts.traff;
return *this;
-};
+}
//-----------------------------------------------------------------------------
inline uint64_t & DIR_TRAFF::operator[](int idx)
{
return traff[idx];
-};
+}
//-----------------------------------------------------------------------------
inline uint64_t DIR_TRAFF::operator[](int idx) const
{
return traff[idx];
-};
+}
//-----------------------------------------------------------------------------
inline DIR_TRAFF DIR_TRAFF::operator+(const DIR_TRAFF & ts)
{
traff[i] = traff[i] + ts.traff[i];
}
return *this;
-};
+}
//-----------------------------------------------------------------------------
inline std::ostream & operator<<(std::ostream & o, const DIR_TRAFF & traff)
{
class USERS {
public:
+ virtual ~USERS() {}
virtual int FindByName(const std::string & login, USER_PTR * user) = 0;
virtual bool TariffInUse(const std::string & tariffName) const = 0;
virtual int Add(const std::string & login, const ADMIN * admin) = 0;
virtual void Del(const std::string & login, const ADMIN * admin) = 0;
+ virtual bool Authorize(const std::string & login, uint32_t ip,
+ uint32_t enabledDirs, const AUTH * auth) = 0;
+ virtual bool Unauthorize(const std::string & login, const AUTH * auth) = 0;
+
virtual int ReadUsers() = 0;
- virtual int GetUserNum() const = 0;
+ virtual size_t Count() const = 0;
virtual int FindByIPIdx(uint32_t ip, USER_PTR * user) const = 0;
virtual bool IsIPInIndex(uint32_t ip) const = 0;
#define __VERSION_H__
// Stargazer version
-#define SERVER_VERSION "2.407-p1"
+#define SERVER_VERSION "2.408-rc2"
#endif
SRCS = ./main.cpp \
./settings_impl.cpp
-STGLIBS = -lstglogger \
- -lstgcommon \
- -ldotconfpp \
- -lstgcrypto
+STGLIBS = dotconfpp \
+ conffiles \
+ logger \
+ crypto \
+ common
-LIBS += $(LIB_THREAD)
+STGLIBS_INCS = $(addprefix -I ../../stglibs/,$(addsuffix .lib/include,$(STGLIBS)))
+STGLIBS_LIBS = $(addprefix -L ../../stglibs/,$(addsuffix .lib,$(STGLIBS)))
+
+LIBS += $(addprefix -lstg,$(STGLIBS)) $(LIB_THREAD)
ifeq ($(OS),linux)
LIBS += -ldl
else
-LIBS += -lc
+LIBS += -lc -liconv
endif
-SEARCH_DIRS = -I $(DIR_INCLUDE)
+SEARCH_DIRS = -I ../../include
OBJS = $(notdir $(patsubst %.cpp, %.o, $(patsubst %.c, %.o, $(SRCS))))
-CXXFLAGS += -Wall
-LDFLAGS += -Wl,-E -L$(DIR_LIB) -Wl,-rpath,$(DIR_LIB)
-
-vpath %.so $(DIR_LIB)
+CXXFLAGS += $(DEFS) $(STGLIBS_INCS) $(SEARCH_DIRS)
+CFLAGS += $(DEFS) $(STGLIBS_INCS) $(SEARCH_DIRS)
+LDFLAGS += -Wl,-E $(STGLIBS_LIBS)
.PHONY: all clean distclean libs plugins install uninstall
all: libs plugins $(PROG) ../../Makefile.conf
plugins: libs
$(MAKE) -C $(DIR_PLUGINS)
-$(PROG): $(OBJS) $(STGLIBS)
- $(CC) $^ $(LDFLAGS) $(LIBS) -o $(PROG)
+$(PROG): $(OBJS)
+ $(CXX) $^ $(LDFLAGS) $(LIBS) -o $(PROG)
clean:
rm -f deps $(PROG) *.o tags *.*~ .OS
endif
deps: $(SRCS) ../../Makefile.conf
- $(MAKE) -C $(DIR_LIBSRC) includes
+ $(MAKE) -C $(DIR_LIBSRC)
@>deps ;\
for file in $(SRCS); do\
- echo "`$(CC) $(CXXFLAGS) $(SEARCH_DIRS) -MM $$file` Makefile" >> deps ;\
- echo -e '\t$$(CC) -c $$< $(CXXFLAGS) $(SEARCH_DIRS) $(DEFS)' >> deps ;\
+ echo "`$(CC) $(CXXFLAGS) -MM $$file` Makefile" >> deps ;\
+ printf '%b\n' '\t$$(CC) -c $$< $(CXXFLAGS)' >> deps ;\
done
-
-
VAR_DIR="./inst/var/stargazer"
DEFS="-DDEBUG"
MAKEOPTS="-j1"
-CXXFLAGS="$CXXFLAGS -g3 -W -Wall -I/usr/local/include"
+CXXFLAGS="$CXXFLAGS -ggdb3 -W -Wall -I/usr/local/include"
LDFLAGS="$LDFLAGS -L/usr/local/lib"
if [ "$sys" = "Linux" ]
if [ "$OS" = "linux" ]
then
DEFS="$DEFS -DLINUX"
- SHELL="/bin/bash"
LIB_THREAD=-lpthread
else
if [ "$OS" = "bsd" ]
LIB_THREAD=-lc_r
fi
fi
- SHELL="/usr/local/bin/bash"
fi
if [ -z "$CC" ]
echo -n "Checking endianess... "
echo "int main() { int probe = 0x00000001; return *(char *)&probe; }" > build_check.c
-$CC $CXXFLAGS $LDFLAGS -L/usr/lib/mysql -L/usr/local/lib/mysql build_check.c -o fake > /dev/null 2> /dev/null
+$CC $CFLAGS $LDFLAGS -L/usr/lib/mysql -L/usr/local/lib/mysql build_check.c -o fake > /dev/null 2> /dev/null
if [ $? != 0 ]
then
echo "FAIL!"
then
ARCH=le
CXXFLAGS="$CXXFLAGS -DARCH_LE"
+ CFLAGS="$CFLAGS -DARCH_LE"
echo "Little Endian"
else
ARCH=be
CXXFLAGS="$CXXFLAGS -DARCH_BE"
+ CFLAGS="$CFLAGS -DARCH_BE"
echo "Big Endian"
fi
fi
rm -f fake
echo -n "Checking for -lfbclient... "
-$CC $CXXFLAGS $LDFLAGS build_check.c -lfbclient $LIB_THREAD -o fake > /dev/null 2> /dev/null
+$CC $CFLAGS $LDFLAGS build_check.c -lfbclient $LIB_THREAD -o fake > /dev/null 2> /dev/null
if [ $? != 0 ]
then
CHECK_FBCLIENT=no
then
echo "no";
echo -n "Checking for -lmysqlclient... "
- $CC $CXXFLAGS $LDFLAGS build_check.c -lmysqlclient_r $LIB_THREAD -o fake > /dev/null 2> /dev/null
+ $CC $CFLAGS $LDFLAGS build_check.c -lmysqlclient_r $LIB_THREAD -o fake > /dev/null 2> /dev/null
if [ $? != 0 ]
then
CHECK_MYSQLCLIENT=no
CHECK_MYSQLCLIENT=no
echo "no"
else
- #CXXFLAGS="$CXXFLAGS $MYSQL_CFLAGS"
echo "[$MYSQL_CFLAGS]"
echo -n "Checking for mysql_config --libs_r... "
MYSQL_LDFLAGS=`mysql_config --libs_r 2> /dev/null`
echo "no"
else
CHECK_MYSQLCLIENT=yes
- #LDFLAGS="$LDFLAGS $MYSQL_LDFLAGS"
echo "[$MYSQL_LDFLAGS]"
fi
fi
then
echo "no";
echo -n "Checking for -lpq... "
- $CC $CXXFLAGS $LDFLAGS build_check.c -lpq $LIB_THREAD -o fake > /dev/null 2> /dev/null
+ $CC $CFLAGS $LDFLAGS build_check.c -lpq $LIB_THREAD -o fake > /dev/null 2> /dev/null
if [ $? != 0 ]
then
CHECK_PQ=no
echo -n "$plugin " >> $CONFFILE
done
echo "" >> $CONFFILE
-echo "SHELL=$SHELL" >> $CONFFILE
echo "CXXFLAGS=$CXXFLAGS" >> $CONFFILE
+echo "CFLAGS=$CFLAGS" >> $CONFFILE
echo "LDFLAGS=$LDFLAGS" >> $CONFFILE
echo "LIB_THREAD=$LIB_THREAD" >> $CONFFILE
echo "PREFIX=$PREFIX" >> $CONFFILE
SRCS = ./rlm_stg.cpp \
./stg_client.cpp
-STGLIBS = -lstgcommon \
- -lstgcrypto
+STGLIBS = crypto \
+ common
+
+STGLIBS_INCS = $(addprefix -I ../../stglibs/,$(addsuffix .lib/include,$(STGLIBS)))
+STGLIBS_LIBS = $(addprefix -L ../../stglibs/,$(addsuffix .lib,$(STGLIBS)))
-LIBS += $(LIB_THREAD)
+LIBS += $(addprefix -lstg,$(STGLIBS)) $(LIB_THREAD)
ifeq ($(OS),linux)
LIBS += -ldl
else
LIBS += -lintl \
- -lc
+ -lc \
+ -liconv
endif
-SEARCH_DIRS = -I $(DIR_INCLUDE)
+SEARCH_DIRS = -I ../../include
OBJS = $(notdir $(patsubst %.cpp, %.o, $(patsubst %.c, %.o, $(SRCS))))
-CXXFLAGS += -Wall -fPIC -I./
-LDFLAGS += -shared -L$(DIR_LIB) -Wl,-rpath,$(PREFIX)/usr/lib/stg
-
-vpath %.so $(DIR_LIB)
+CXXFLAGS += -fPIC $(DEFS) $(STGLIBS_INCS) $(SEARCH_DIRS)
+CFLAGS += $(DEFS) $(STGLIBS_INCS) $(SEARCH_DIRS)
+LDFLAGS += -shared -Wl,-rpath,$(PREFIX)/usr/lib/stg -Wl,-E $(STGLIBS_LIBS)
.PHONY: all clean distclean libs install uninstall install-bin uninstall-bin
all: libs $(PROG) ../../Makefile.conf
libs:
$(MAKE) -C $(DIR_LIBSRC)
-$(PROG): $(OBJS) $(STGLIBS)
- $(CC) $^ $(LDFLAGS) -o $(PROG) $(LIBS)
+$(PROG): $(OBJS)
+ $(CXX) $^ $(LDFLAGS) -o $(PROG) $(LIBS)
clean:
rm -f deps $(PROG) *.o tags *.*~ .OS
endif
deps: $(SRCS) ../../Makefile.conf
- $(MAKE) -C $(DIR_LIBSRC) includes
+ $(MAKE) -C $(DIR_LIBSRC)
@>deps ;\
for file in $(SRCS); do\
- echo "`$(CC) $(CXXFLAGS) $(SEARCH_DIRS) -MM $$file` Makefile" >> deps ;\
- echo -e '\t$$(CC) -c $$< $(CXXFLAGS) $(SEARCH_DIRS) $(DEFS)' >> deps ;\
+ echo "`$(CC) $(CXXFLAGS) -MM $$file` Makefile" >> deps ;\
+ printf '%b\n' '\t$$(CC) -c $$< $(CXXFLAGS)' >> deps ;\
done
-
-
then
DEFS="-DDEBUG"
MAKEOPTS="-j1"
- CXXFLAGS="$CXXFLAGS -g3 -W -Wall"
+ CXXFLAGS="$CXXFLAGS -ggdb3 -W -Wall"
else
MAKEOPTS="-j1"
fi
then
DEFS="$DEFS -DLINUX"
LIB_THREAD=-lpthread
- SHELL="/bin/bash"
else
if [ "$OS" = "bsd" ]
then
LIB_THREAD=-lc_r
fi
fi
- SHELL="/usr/local/bin/bash"
CXXFLAGS="$CXXFLAGS -DHAVE_CLOSEFROM"
fi
echo -n "Checking endianess... "
echo "int main() { int probe = 0x00000001; return *(char *)&probe; }" > build_check.c
-$CC $CXXFLAGS $LDFLAGS build_check.c -o fake > /dev/null 2> /dev/null
+$CC $CFLAGS $LDFLAGS build_check.c -o fake > /dev/null 2> /dev/null
if [ $? != 0 ]
then
echo "FAIL!"
then
ARCH=le
CXXFLAGS="$CXXFLAGS -DARCH_LE"
+ CFLAGS="$CFLAGS -DARCH_LE"
echo "Little Endian"
else
ARCH=be
CXXFLAGS="$CXXFLAGS -DARCH_BE"
+ CFLAGS="$CFLAGS -DARCH_BE"
echo "Big Endian"
fi
fi
done
echo "" >> $CONFFILE
echo "CXXFLAGS=$CXXFLAGS" >> $CONFFILE
+echo "CFLAGS=$CFLAGS" >> $CONFFILE
echo "LDFLAGS=$LDFLAGS" >> $CONFFILE
echo "LIB_THREAD=$LIB_THREAD" >> $CONFFILE
echo "PREFIX=$PREFIX" >> $CONFFILE
echo "DATA_MODE=$DATA_MODE" >> $CONFFILE
echo "DIR_MODE=$DIR_MODE" >> $CONFFILE
echo "OWNER=$OWNER" >> $CONFFILE
-echo "SHELL=$SHELL" >> $CONFFILE
$MAKE $MAKEOPTS
./listener.cpp \
./pidfile.cpp
-STGLIBS = -lstglogger \
- -lstgcommon \
- -lstgcrypto \
- -lstgscriptexecuter \
- -lstgconffiles
+STGLIBS = scriptexecuter \
+ conffiles \
+ logger \
+ locker \
+ crypto \
+ common
-LIBS += $(LIB_THREAD)
+STGLIBS_INCS = $(addprefix -I ../../stglibs/,$(addsuffix .lib/include,$(STGLIBS)))
+STGLIBS_LIBS = $(addprefix -L ../../stglibs/,$(addsuffix .lib,$(STGLIBS)))
-#ifeq ($(OS),linux)
-#LIBS += -ldl
-#else
-#LIBS += -lc
-#endif
+LIBS += $(addprefix -lstg,$(STGLIBS)) $(LIB_THREAD)
-SEARCH_DIRS = -I $(DIR_INCLUDE)
+ifneq ($(OS),linux)
+LIBS += -liconv
+endif
-OBJS = $(notdir $(patsubst %.cpp, %.o, $(patsubst %.c, %.o, $(SRCS))))
+SEARCH_DIRS = -I ../../include
-CXXFLAGS += -Wall
-LDFLAGS += -Wl,-E -L$(DIR_LIB) -Wl,-rpath,$(PREFIX)/usr/lib/stg -Wl,-rpath-link,$(DIR_LIB)
+OBJS = $(notdir $(patsubst %.cpp, %.o, $(patsubst %.c, %.o, $(SRCS))))
-vpath %.so $(DIR_LIB)
+CXXFLAGS += $(DEFS) $(STGLIBS_INCS) $(SEARCH_DIRS)
+CFLAGS += $(DEFS) $(STGLIBS_INCS) $(SEARCH_DIRS)
+LDFLAGS += -Wl,-E $(STGLIBS_LIBS)
.PHONY: all clean distclean libs install uninstall
all: libs $(PROG) ../../Makefile.conf
libs:
$(MAKE) -C $(DIR_LIBSRC)
-$(PROG): $(OBJS) $(STGLIBS)
- $(CC) $^ $(LDFLAGS) $(LIBS) -o $(PROG)
+$(PROG): $(OBJS)
+ $(CXX) $^ $(LDFLAGS) $(LIBS) -o $(PROG)
clean:
rm -f deps $(PROG) *.o tags *.*~ .OS
endif
deps: $(SRCS) ../../Makefile.conf
- $(MAKE) -C $(DIR_LIBSRC) includes
+ $(MAKE) -C $(DIR_LIBSRC)
@>deps ;\
for file in $(SRCS); do\
- echo "`$(CC) $(CXXFLAGS) $(SEARCH_DIRS) -MM $$file` Makefile" >> deps ;\
- echo -e '\t$$(CC) -c $$< $(CXXFLAGS) $(SEARCH_DIRS) $(DEFS)' >> deps ;\
+ echo "`$(CC) $(CXXFLAGS) -MM $$file` Makefile" >> deps ;\
+ printf '%b\n' '\t$$(CC) -c $$< $(CXXFLAGS)' >> deps ;\
done
-
-
then
DEFS="-DDEBUG"
MAKEOPTS="-j1"
- CXXFLAGS="$CXXFLAGS -g3 -W -Wall"
+ CXXFLAGS="$CXXFLAGS -ggdb3 -W -Wall"
else
MAKEOPTS="-j1"
fi
then
DEFS="$DEFS -DLINUX"
LIB_THREAD=-lpthread
- SHELL="/bin/bash"
else
if [ "$OS" = "bsd" ]
then
LIB_THREAD=-lc_r
fi
fi
- SHELL="/usr/local/bin/bash"
fi
if [ -z "$CC" ]
echo -n "Checking endianess... "
echo "int main() { int probe = 0x00000001; return *(char *)&probe; }" > build_check.c
-$CC $CXXFLAGS $LDFLAGS build_check.c -o fake > /dev/null 2> /dev/null
+$CC $CFLAGS $LDFLAGS build_check.c -o fake > /dev/null 2> /dev/null
if [ $? != 0 ]
then
echo "FAIL!"
then
ARCH=le
CXXFLAGS="$CXXFLAGS -DARCH_LE"
+ CFLAGS="$CFLAGS -DARCH_LE"
echo "Little Endian"
else
ARCH=be
CXXFLAGS="$CXXFLAGS -DARCH_BE"
+ CFLAGS="$CFLAGS -DARCH_BE"
echo "Big Endian"
fi
fi
done
echo "" >> $CONFFILE
echo "LIB_THREAD=$LIB_THREAD" >> $CONFFILE
-echo "SHELL=$SHELL" >> $CONFFILE
echo "CXXFLAGS=$CXXFLAGS" >> $CONFFILE
+echo "CFLAGS=$CFLAGS" >> $CONFFILE
echo "LDFLAGS=$LDFLAGS" >> $CONFFILE
echo "PREFIX=$PREFIX" >> $CONFFILE
echo "BIN_MODE=$BIN_MODE" >> $CONFFILE
printfd(__FILE__, "LISTENER::Stop()\n");
-usleep(500000);
+struct timespec ts = {0, 500000000};
+nanosleep(&ts, NULL);
if (!processorStopped)
{
//5 seconds to thread stops itself
for (int i = 0; i < 25 && !processorStopped; i++)
{
- usleep(200000);
+ struct timespec ts = {0, 200000000};
+ nanosleep(&ts, NULL);
}
//after 5 seconds waiting thread still running. now killing it
//5 seconds to thread stops itself
for (int i = 0; i < 25 && !receiverStopped; i++)
{
- usleep(200000);
+ struct timespec ts = {0, 200000000};
+ nanosleep(&ts, NULL);
}
//after 5 seconds waiting thread still running. now killing it
//-----------------------------------------------------------------------------
void * LISTENER::Run(void * d)
{
+sigset_t signalSet;
+sigfillset(&signalSet);
+pthread_sigmask(SIG_BLOCK, &signalSet, NULL);
+
LISTENER * listener = static_cast<LISTENER *>(d);
listener->Runner();
//-----------------------------------------------------------------------------
void * LISTENER::RunProcessor(void * d)
{
+sigset_t signalSet;
+sigfillset(&signalSet);
+pthread_sigmask(SIG_BLOCK, &signalSet, NULL);
+
LISTENER * listener = static_cast<LISTENER *>(d);
listener->ProcessorRunner();
while (running)
{
- usleep(500000);
+ struct timespec ts = {0, 500000000};
+ nanosleep(&ts, NULL);
if (!pending.empty())
ProcessPending();
ProcessTimeouts();
printfd(__FILE__, "Connect %s\n", data.login.c_str());
if (access(scriptOnConnect.c_str(), X_OK) == 0)
{
- if (ScriptExec(scriptOnConnect + " " + data.params))
+ if (ScriptExec((scriptOnConnect + " " + data.params).c_str()))
{
WriteServLog("Script %s cannot be executed for an unknown reason.", scriptOnConnect.c_str());
return true;
printfd(__FILE__, "Disconnect %s\n", data.login.c_str());
if (access(scriptOnDisconnect.c_str(), X_OK) == 0)
{
- if (ScriptExec(scriptOnDisconnect + " " + data.params))
+ if (ScriptExec((scriptOnDisconnect + " " + data.params).c_str()))
{
WriteServLog("Script %s cannot be executed for an unknown reson.", scriptOnDisconnect.c_str());
return true;
return false;
}
//-----------------------------------------------------------------------------
-bool LISTENER::WaitPackets(int sd) const
-{
-fd_set rfds;
-FD_ZERO(&rfds);
-FD_SET(sd, &rfds);
-
-struct timeval tv;
-tv.tv_sec = 0;
-tv.tv_usec = 500000;
-
-int res = select(sd + 1, &rfds, NULL, NULL, &tv);
-if (res == -1) // Error
- {
- if (errno != EINTR)
- {
- printfd(__FILE__, "Error on select: '%s'\n", strerror(errno));
- }
- return false;
- }
-
-if (res == 0) // Timeout
- {
- return false;
- }
-
-return true;
-}
-//-----------------------------------------------------------------------------
inline
void InitEncrypt(BLOWFISH_CTX * ctx, const std::string & password)
{
// Networking stuff
bool PrepareNet();
bool FinalizeNet();
- bool WaitPackets(int sd) const;
bool RecvPacket();
// Parsing stuff
bool CheckHeader(const RS_PACKET_HEADER & header) const;
#define START_FILE "/._ST_ART_ED_"
-static bool childExited = false;
set<pid_t> executersPid;
-static pid_t stgChildPid;
volatile time_t stgTime = time(NULL);
-class STG_STOPPER
-{
-public:
- STG_STOPPER() { nonstop = true; }
- bool GetStatus() const { return nonstop; };
- void Stop(const char * __file__, int __line__)
- {
- #ifdef NO_DAEMON
- printfd(__FILE__, "rscriptd stopped at %s:%d\n", __file__, __line__);
- #endif
- nonstop = false;
- }
-private:
- bool nonstop;
-};
-//-----------------------------------------------------------------------------
-STG_STOPPER nonstop;
-//-----------------------------------------------------------------------------
-void CatchPROF(int)
-{
-}
-//-----------------------------------------------------------------------------
-void CatchUSR1(int)
-{
-}
-//-----------------------------------------------------------------------------
-void CatchTERM(int sig)
-{
-/*
- *Function Name:CatchINT
- *Parameters: sig_num - signal number
- *Description: INT signal handler
- *Returns: Nothing
- */
-STG_LOGGER & WriteServLog = GetStgLogger();
-WriteServLog("Shutting down... %d", sig);
-
-nonstop.Stop(__FILE__, __LINE__);
-
-struct sigaction newsa, oldsa;
-sigset_t sigmask;
-
-sigemptyset(&sigmask);
-sigaddset(&sigmask, SIGTERM);
-newsa.sa_handler = SIG_IGN;
-newsa.sa_mask = sigmask;
-newsa.sa_flags = 0;
-sigaction(SIGTERM, &newsa, &oldsa);
-
-sigemptyset(&sigmask);
-sigaddset(&sigmask, SIGINT);
-newsa.sa_handler = SIG_IGN;
-newsa.sa_mask = sigmask;
-newsa.sa_flags = 0;
-sigaction(SIGINT, &newsa, &oldsa);
-}
-//-----------------------------------------------------------------------------
-void CatchPIPE(int)
-{
-STG_LOGGER & WriteServLog = GetStgLogger();
-WriteServLog("Broken pipe!");
-}
-//-----------------------------------------------------------------------------
-void CatchHUP(int)
-{
-}
-//-----------------------------------------------------------------------------
-void CatchCHLD(int)
-{
-int status;
-pid_t childPid;
-childPid = waitpid(-1, &status, WNOHANG);
-
-set<pid_t>::iterator pid;
-pid = executersPid.find(childPid);
-if (pid != executersPid.end())
- {
- executersPid.erase(pid);
- }
-if (childPid == stgChildPid)
- {
- childExited = true;
- }
-}
-//-----------------------------------------------------------------------------
-void SetSignalHandlers()
-{
-struct sigaction newsa, oldsa;
-sigset_t sigmask;
-
-sigemptyset(&sigmask);
-sigaddset(&sigmask, SIGTERM);
-newsa.sa_handler = CatchTERM;
-newsa.sa_mask = sigmask;
-newsa.sa_flags = 0;
-sigaction(SIGTERM, &newsa, &oldsa);
-
-sigemptyset(&sigmask);
-sigaddset(&sigmask, SIGUSR1);
-newsa.sa_handler = CatchUSR1;
-newsa.sa_mask = sigmask;
-newsa.sa_flags = 0;
-sigaction(SIGUSR1, &newsa, &oldsa);
-
-sigemptyset(&sigmask);
-sigaddset(&sigmask, SIGINT);
-newsa.sa_handler = CatchTERM;
-newsa.sa_mask = sigmask;
-newsa.sa_flags = 0;
-sigaction(SIGINT, &newsa, &oldsa);
-
-sigemptyset(&sigmask);
-sigaddset(&sigmask, SIGPIPE);
-newsa.sa_handler = CatchPIPE;
-newsa.sa_mask = sigmask;
-newsa.sa_flags = 0;
-sigaction(SIGPIPE, &newsa, &oldsa);
-
-sigemptyset(&sigmask);
-sigaddset(&sigmask, SIGHUP);
-newsa.sa_handler = CatchHUP;
-newsa.sa_mask = sigmask;
-newsa.sa_flags = 0;
-sigaction(SIGHUP, &newsa, &oldsa);
-
-sigemptyset(&sigmask);
-sigaddset(&sigmask, SIGCHLD);
-newsa.sa_handler = CatchCHLD;
-newsa.sa_mask = sigmask;
-newsa.sa_flags = 0;
-sigaction(SIGCHLD, &newsa, &oldsa);
-}
//-----------------------------------------------------------------------------
void KillExecuters()
{
}
}
//-----------------------------------------------------------------------------
+#ifdef LINUX
int StartScriptExecuter(char * procName, int msgKey, int * msgID)
+#else
+int StartScriptExecuter(char *, int msgKey, int * msgID)
+#endif
{
STG_LOGGER & WriteServLog = GetStgLogger();
//close(1);
//close(2);
//setsid();
- Executer(msgKey, *msgID, executerPid, procName);
+#ifdef LINUX
+ Executer(*msgID, executerPid, procName);
+#else
+ Executer(*msgID, executerPid);
+#endif
return 1;
default: // Parent
if (executersPid.empty())
- Executer(msgKey, *msgID, executerPid, NULL);
+#ifdef LINUX
+ Executer(*msgID, executerPid, NULL);
+#else
+ Executer(*msgID, executerPid);
+#endif
executersPid.insert(executerPid);
}
return 0;
#endif
{
#ifndef NO_DAEMON
-stgChildPid = fork();
+pid_t childPid = fork();
-switch (stgChildPid)
+switch (childPid)
{
case -1: // Failure
return -1;
//-----------------------------------------------------------------------------
int main(int argc, char * argv[])
{
-
-/*
- Initialization order:
- - Logger
- - Config
- - Set signal nandlers
- - Fork and exit
- */
-
CONFIGFILE * cfg = NULL;
LISTENER * listener = NULL;
int msgID = -11;
cfg->ReadString("ScriptOnConnect", &onConnect, "/etc/rscriptd/OnConnect");
cfg->ReadString("ScriptOnDisconnect", &onDisconnect, "/etc/rscriptd/OnDisconnect");
-SetSignalHandlers();
if (ForkAndWait(confDir) < 0)
{
STG_LOGGER & WriteServLog = GetStgLogger();
WriteServLog("rscriptd started successfully.");
WriteServLog("+++++++++++++++++++++++++++++++++++++++++++++");
-while (nonstop.GetStatus())
+sigset_t signalSet;
+sigfillset(&signalSet);
+pthread_sigmask(SIG_BLOCK, &signalSet, NULL);
+
+while (true)
{
- usleep(100000);
+ sigfillset(&signalSet);
+ int sig = 0;
+ printfd(__FILE__, "Before sigwait\n");
+ sigwait(&signalSet, &sig);
+ printfd(__FILE__, "After sigwait. Signal: %d\n", sig);
+ bool stop = false;
+ switch (sig)
+ {
+ case SIGTERM:
+ stop = true;
+ break;
+ case SIGINT:
+ stop = true;
+ break;
+ default:
+ WriteServLog("Ignore signel %d", sig);
+ break;
+ }
+ if (stop)
+ break;
}
listener->Stop();
Password=123456
Port=9999
UserTimeout=60
-ScriptOnConnect=/etc/rscriptd/OnConnect
-ScriptOnDisconnect=/etc/rscriptd/OnDisconnect
+ScriptOnConnect=/etc/stargazer/OnConnect
+ScriptOnDisconnect=/etc/stargazer/OnDisconnect
./settings_impl.cpp \
./web.cpp
-STGLIBS = -lstgconffiles \
- -lstgcrypto \
- -lstgcommon \
- -lstgia
+STGLIBS = conffiles \
+ ia \
+ crypto \
+ common
-LIBS += $(LIB_THREAD)
+STGLIBS_INCS = $(addprefix -I ../../stglibs/,$(addsuffix .lib/include,$(STGLIBS)))
+STGLIBS_LIBS = $(addprefix -L ../../stglibs/,$(addsuffix .lib,$(STGLIBS)))
-ifeq ($(OS),linux)
-else
+LIBS += $(addprefix -lstg,$(STGLIBS)) $(LIB_THREAD)
+
+ifneq ($(OS),linux)
LIBS += -lintl \
- -lc
+ -lc \
+ -liconv
endif
-SEARCH_DIRS = -I $(DIR_INCLUDE)
+SEARCH_DIRS = -I ../../include
OBJS = $(notdir $(patsubst %.cpp, %.o, $(patsubst %.c, %.o, $(SRCS))))
-CXXFLAGS += -Wall
-LDFLAGS += -Wl,-E -L$(DIR_LIB) -Wl,-rpath,$(PREFIX)/usr/lib/stg -Wl,-rpath-link,$(DIR_LIB)
-
-vpath %.so $(DIR_LIB)
+CXXFLAGS += $(DEFS) $(STGLIBS_INCS) $(SEARCH_DIRS)
+CFLAGS += $(DEFS) $(STGLIBS_INCS) $(SEARCH_DIRS)
+LDFLAGS += -Wl,-E $(STGLIBS_LIBS)
.PHONY: all clean distclean libs install uninstall install-bin install-data uninstall-bin uninstall-data
all: libs $(PROG) ../../Makefile.conf
libs:
$(MAKE) -C $(DIR_LIBSRC)
-$(PROG): $(OBJS) $(STGLIBS)
- $(CC) $^ $(LDFLAGS) -o $(PROG) $(LIBS)
+$(PROG): $(OBJS)
+ $(CXX) $^ $(LDFLAGS) -o $(PROG) $(LIBS)
clean:
rm -f deps $(PROG) *.o tags *.*~ .OS
endif
deps: $(SRCS) ../../Makefile.conf sgauth.css
- $(MAKE) -C $(DIR_LIBSRC) includes
+ $(MAKE) -C $(DIR_LIBSRC)
@>deps ;\
./make_css.sh
for file in $(SRCS); do\
- echo "`$(CC) $(CXXFLAGS) $(SEARCH_DIRS) -MM $$file` Makefile" >> deps ;\
- echo -e '\t$$(CC) -c $$< $(CXXFLAGS) $(SEARCH_DIRS) $(DEFS)' >> deps ;\
+ echo "`$(CC) $(CXXFLAGS) -MM $$file` Makefile" >> deps ;\
+ printf '%b\n' '\t$$(CC) -c $$< $(CXXFLAGS)' >> deps ;\
done
then
DEFS="-DDEBUG"
MAKEOPTS="-j1"
- CXXFLAGS="$CXXFLAGS -g3 -W -Wall"
+ CXXFLAGS="$CXXFLAGS -ggdb3 -W -Wall"
else
MAKEOPTS="-j1"
fi
then
DEFS="$DEFS -DLINUX"
LIB_THREAD=-lpthread
- SHELL="/bin/bash"
else
if [ "$OS" = "bsd" ]
then
LIB_THREAD=-lc_r
fi
fi
- SHELL="/usr/local/bin/bash"
fi
if [ -z "$CC" ]
echo -n "Checking endianess... "
echo "int main() { int probe = 0x00000001; return *(char *)&probe; }" > build_check.c
-$CC $CXXFLAGS $LDFLAGS build_check.c -o fake > /dev/null 2> /dev/null
+$CC $CFLAGS $LDFLAGS build_check.c -o fake > /dev/null 2> /dev/null
if [ $? != 0 ]
then
echo "FAIL!"
then
ARCH=le
CXXFLAGS="$CXXFLAGS -DARCH_LE"
+ CFLAGS="$CFLAGS -DARCH_LE"
echo "Little Endian"
else
ARCH=be
CXXFLAGS="$CXXFLAGS -DARCH_BE"
+ CFLAGS="$CFLAGS -DARCH_BE"
echo "Big Endian"
fi
fi
done
echo "" >> $CONFFILE
echo "LIB_THREAD=$LIB_THREAD" >> $CONFFILE
-echo "SHELL=$SHELL" >> $CONFFILE
echo "CXXFLAGS=$CXXFLAGS" >> $CONFFILE
+echo "CFLAGS=$CFLAGS" >> $CONFFILE
echo "LDFLAGS=$LDFLAGS" >> $CONFFILE
echo "PREFIX=$PREFIX" >> $CONFFILE
echo "BIN_MODE=$BIN_MODE" >> $CONFFILE
while (1)
{
- usleep(200000);
+ struct timespec ts = {0, 200000000};
+ nanosleep(&ts, NULL);
char state[20];
{
}
//-----------------------------------------------------------------------------
-int SETTINGS_IMPL::ParseYesNo(const string & value, bool * val)
-{
-if (0 == strcasecmp(value.c_str(), "yes"))
- {
- *val = true;
- return 0;
- }
-if (0 == strcasecmp(value.c_str(), "no"))
- {
- *val = false;
- return 0;
- }
-
-strError = "Incorrect value \'" + value + "\'.";
-return -1;
-}
-//-----------------------------------------------------------------------------
-int SETTINGS_IMPL::ParseInt(const string & value, int * val)
-{
-if (str2x<int>(value, *val))
- {
- strError = "Cannot convert \'" + value + "\' to integer.";
- return -1;
- }
-return 0;
-}
-//-----------------------------------------------------------------------------
-int SETTINGS_IMPL::ParseUnsigned(const string & value, unsigned * val)
-{
-if (str2x<unsigned>(value, *val))
- {
- strError = "Cannot convert \'" + value + "\' to unsigned integer.";
- return -1;
- }
-return 0;
-}
-//-----------------------------------------------------------------------------
-int SETTINGS_IMPL::ParseIntInRange(const string & value, int min, int max, int * val)
-{
-if (ParseInt(value, val) != 0)
- return -1;
-
-if (*val < min || *val > max)
- {
- strError = "Value \'" + value + "\' out of range.";
- return -1;
- }
-
-return 0;
-}
-//-----------------------------------------------------------------------------
-int SETTINGS_IMPL::ParseUnsignedInRange(const string & value, unsigned min, unsigned max, unsigned * val)
-{
-if (ParseUnsigned(value, val) != 0)
- return -1;
-
-if (*val < min || *val > max)
- {
- strError = "Value \'" + value + "\' out of range.";
- return -1;
- }
-
-return 0;
-}
-//-----------------------------------------------------------------------------
int SETTINGS_IMPL::ReadSettings()
{
CONFIGFILE cf(confFile);
SETTINGS_IMPL();
~SETTINGS_IMPL() {}
int Reload() { return 0; }
- void SetConfFile(const std::string cf) { confFile = cf; }
+ void SetConfFile(const std::string & cf) { confFile = cf; }
int ReadSettings();
const std::string & GetStrError() const { return strError; }
std::string confFile;
std::string strError;
-
- int ParseInt(const std::string & value, int * val);
- int ParseUnsigned(const std::string & value, unsigned * val);
- int ParseIntInRange(const std::string & value, int min, int max, int * val);
- int ParseUnsignedInRange(const std::string & value, unsigned min, unsigned max, unsigned * val);
- int ParseYesNo(const std::string & value, bool * val);
};
#endif
$Date: 2010/03/15 12:58:17 $
*/
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
#include <libintl.h>
+#include <csignal>
+#include <cstdio>
+#include <cstring>
+#include <ctime>
+
#include "stg/common.h"
#include "stg/ia.h"
#include "web.h"
//---------------------------------------------------------------------------
#ifndef WIN32
void * RunWeb(void *)
+{
+sigset_t signalSet;
+sigfillset(&signalSet);
+pthread_sigmask(SIG_BLOCK, &signalSet, NULL);
+
#else
unsigned long WINAPI RunWeb(void *)
-#endif
{
+#endif
while (1)
web->Run();
return NULL;
#ifdef WIN32
Sleep(1000);
#else
- usleep(1000000);
+ struct timespec ts = {1, 0};
+ nanosleep(&ts, NULL);
#endif
exit(0);
}
user.cpp \
proto.cpp
-STGLIBS = -lstgcrypto \
- -lstgcommon \
- -ldotconfpp
+STGLIBS = dotconfpp \
+ locker \
+ crypto \
+ common
-LIBS += $(LIB_THREAD)
+STGLIBS_INCS = $(addprefix -I ../../stglibs/,$(addsuffix .lib/include,$(STGLIBS)))
+STGLIBS_LIBS = $(addprefix -L ../../stglibs/,$(addsuffix .lib,$(STGLIBS)))
+
+LIBS += $(addprefix -lstg,$(STGLIBS)) $(LIB_THREAD)
ifeq ($(OS),linux)
LIBS += -ldl
else
LIBS += -lintl \
- -lc
+ -lc \
+ -liconv
endif
-SEARCH_DIRS = -I $(DIR_INCLUDE)
+SEARCH_DIRS = -I ../../include
OBJS = $(notdir $(patsubst %.cpp, %.o, $(patsubst %.c, %.o, $(SRCS))))
-CXXFLAGS += -Wall
-LDFLAGS += -Wl,-E -L$(DIR_LIB) -Wl,-rpath,$(PREFIX)/usr/lib/stg -Wl,-rpath-link,$(DIR_LIB)
-
-vpath %.so $(DIR_LIB)
+CXXFLAGS += $(DEFS) $(STGLIBS_INCS) $(SEARCH_DIRS)
+CFLAGS += $(DEFS) $(STGLIBS_INCS) $(SEARCH_DIRS)
+LDFLAGS += -Wl,-E $(STGLIBS_LIBS)
.PHONY: all clean distclean libs plugins
all: libs plugins $(PROG) ../../Makefile.conf
plugins: libs
$(MAKE) -C $(DIR_PLUGINS)
-$(PROG): $(OBJS) libs
- $(CXX) $(OBJS) $(LDFLAGS) $(LIBS) $(STGLIBS) -o $(PROG)
+$(PROG): $(OBJS)
+ $(CXX) $^ $(LDFLAGS) $(LIBS) -o $(PROG)
clean:
rm -f deps $(PROG) *.o *.*~
endif
deps: $(SRCS) ../../Makefile.conf
- $(MAKE) -C $(DIR_LIBSRC) includes
+ $(MAKE) -C $(DIR_LIBSRC)
@>deps ;\
for file in $(SRCS); do\
- echo "`$(CC) $(CXXFLAGS) $(SEARCH_DIRS) -MM $$file` Makefile ../../Makefile.conf" >> deps ;\
- echo -e '\t$$(CC) -c $$< $(CXXFLAGS) $(SEARCH_DIRS) $(DEFS)' >> deps ;\
+ echo "`$(CC) $(CXXFLAGS) -MM $$file` Makefile ../../Makefile.conf" >> deps ;\
+ printf '%b\n' '\t$$(CC) -c $$< $(CXXFLAGS)' >> deps ;\
done
then
DEFS="-DDEBUG"
MAKEOPTS="-j1"
- CXXFLAGS="$CXXFLAGS -g3 -W -Wall"
+ CXXFLAGS="$CXXFLAGS -ggdb3 -W -Wall"
else
MAKEOPTS="-j1"
fi
then
DEFS="$DEFS -DLINUX"
LIB_THREAD=-lpthread
- SHELL="/bin/bash"
else
if [ "$OS" = "bsd" ]
then
LIB_THREAD=-lc_r
fi
fi
- SHELL="/usr/local/bin/bash"
fi
if [ -z "$CC" ]
echo -n "Checking endianess... "
echo "int main() { int probe = 0x00000001; return *(char *)&probe; }" > build_check.c
-$CC $CXXFLAGS $LDFLAGS build_check.c -o fake > /dev/null 2> /dev/null
+$CC $CFLAGS $LDFLAGS build_check.c -o fake > /dev/null 2> /dev/null
if [ $? != 0 ]
then
echo "FAIL!"
then
ARCH=le
CXXFLAGS="$CXXFLAGS -DARCH_LE"
+ CFLAGS="$CFLAGS -DARCH_LE"
echo "Little Endian"
else
ARCH=be
CXXFLAGS="$CXXFLAGS -DARCH_BE"
+ CFLAGS="$CFLAGS -DARCH_BE"
echo "Big Endian"
fi
fi
rm -f build_check.c
echo -n "Checking for -lfbclient... "
-$CC $CXXFLAGS $LDFLAGS build_check.c -lfbclient $LIB_THREAD -o fake > /dev/null 2> /dev/null
+$CC $CFLAGS $LDFLAGS build_check.c -lfbclient $LIB_THREAD -o fake > /dev/null 2> /dev/null
if [ $? != 0 ]
then
CHECK_FBCLIENT=no
then
echo "no";
echo -n "Checking for -lmysqlclient... "
- $CC $CXXFLAGS $LDFLAGS build_check.c -lmysqlclient_r $LIB_THREAD -o fake > /dev/null 2> /dev/null
+ $CC $CFLAGS $LDFLAGS build_check.c -lmysqlclient_r $LIB_THREAD -o fake > /dev/null 2> /dev/null
if [ $? != 0 ]
then
CHECK_MYSQLCLIENT=no
CHECK_MYSQLCLIENT=no
echo "no"
else
- #CXXFLAGS="$CXXFLAGS $MYSQL_CFLAGS"
echo "[$MYSQL_CFLAGS]"
echo -n "Checking for mysql_config --libs_r... "
MYSQL_LDFLAGS=`mysql_config --libs_r 2> /dev/null`
echo "no"
else
CHECK_MYSQLCLIENT=yes
- #LDFLAGS="$LDFLAGS $MYSQL_LDFLAGS"
echo "[$MYSQL_LDFLAGS]"
fi
fi
then
echo "no";
echo -n "Checking for -lpq... "
- $CC $CXXFLAGS $LDFLAGS build_check.c -lpq $LIB_THREAD -o fake > /dev/null 2> /dev/null
+ $CC $CFLAGS $LDFLAGS build_check.c -lpq $LIB_THREAD -o fake > /dev/null 2> /dev/null
if [ $? != 0 ]
then
CHECK_PQ=no
done
echo "" >> $CONFFILE
echo "LIB_THREAD=$LIB_THREAD" >> $CONFFILE
-echo "SHELL=$SHELL" >> $CONFFILE
echo "CXXFLAGS=$CXXFLAGS" >> $CONFFILE
+echo "CFLAGS=$CFLAGS" >> $CONFFILE
echo "LDFLAGS=$LDFLAGS" >> $CONFFILE
echo "PREFIX=$PREFIX" >> $CONFFILE
echo "BIN_MODE=$BIN_MODE" >> $CONFFILE
running = true;
while (running)
{
- usleep(200000);
+ struct timespec ts = {0, 200000000};
+ nanosleep(&ts, NULL);
}
proto.Stop();
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
+#include <csignal>
#include <cerrno>
#include <cstring>
#include <cassert>
void * PROTO::Runner(void * data)
{
+sigset_t signalSet;
+sigfillset(&signalSet);
+pthread_sigmask(SIG_BLOCK, &signalSet, NULL);
+
PROTO * protoPtr = static_cast<PROTO *>(data);
protoPtr->Run();
return NULL;
#ifndef __PROTO_H__
#define __PROTO_H__
+#ifndef LINUX
+#include <netinet/in_systm.h>
+#endif
#include <netinet/ip.h>
#include <pthread.h>
#include <poll.h>
{
}
//-----------------------------------------------------------------------------
-int ParseYesNo(const std::string & value, bool * val)
-{
-if (0 == strcasecmp(value.c_str(), "yes"))
- {
- *val = true;
- return 0;
- }
-if (0 == strcasecmp(value.c_str(), "no"))
- {
- *val = false;
- return 0;
- }
-
-return -1;
-}
-//-----------------------------------------------------------------------------
-int ParseInt(const std::string & value, int * val)
-{
-if (str2x<int>(value, *val))
- return -1;
-
-return 0;
-}
-//-----------------------------------------------------------------------------
-int ParseUnsigned(const std::string & value, unsigned * val)
-{
-if (str2x<unsigned>(value, *val))
- return -1;
-
-return 0;
-}
-//-----------------------------------------------------------------------------
-int ParseIntInRange(const std::string & value, int min, int max, int * val)
-{
-if (ParseInt(value, val) != 0)
- return -1;
-
-if (*val < min || *val > max)
- return -1;
-
-return 0;
-}
-//-----------------------------------------------------------------------------
-int ParseUnsignedInRange(const std::string & value, unsigned min, unsigned max, unsigned * val)
-{
-if (ParseUnsigned(value, val) != 0)
- return -1;
-
-if (*val < min || *val > max)
- return -1;
-
-return 0;
-}
-//-----------------------------------------------------------------------------
int ParseModuleSettings(const DOTCONFDocumentNode * node, std::vector<PARAM_VALUE> * params)
{
assert(node && "DOTCONFDocumentNode must not be NULL!");
SETTINGS();
~SETTINGS() {}
int Reload() { return 0; }
- void SetConfFile(const std::string cf) { confFile = cf; }
+ void SetConfFile(const std::string & cf) { confFile = cf; }
int ReadSettings();
const std::string & GetStrError() const { return strError; }
+#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
+#include <unistd.h> // close
#include <cstring>
#include <cerrno>
close(sock);
}
-const USER & USER::operator=(const USER & rvalue)
+USER & USER::operator=(const USER & rvalue)
{
login = rvalue.login;
password = rvalue.password;
USER(const USER & rvalue);
~USER();
- const USER & operator=(const USER & rvalue);
+ USER & operator=(const USER & rvalue);
bool InitNetwork();
SRCS = ./main.cpp \
./common_sg.cpp
-STGLIBS = -lstgconffiles \
- -lstgcommon \
- -lstgcrypto \
- -lstgsrvconf
+STGLIBS = conffiles \
+ srvconf \
+ crypto \
+ common
-LIBS += -lexpat \
- $(LIB_THREAD)
+STGLIBS_INCS = $(addprefix -I ../../stglibs/,$(addsuffix .lib/include,$(STGLIBS)))
+STGLIBS_LIBS = $(addprefix -L ../../stglibs/,$(addsuffix .lib,$(STGLIBS)))
+
+LIBS += $(addprefix -lstg,$(STGLIBS)) -lexpat $(LIB_THREAD)
ifeq ($(OS),linux)
-LIBS += -ldl
else
LIBS += -lc \
-liconv
endif
-SEARCH_DIRS = -I $(DIR_INCLUDE)
+SEARCH_DIRS = -I ../../include
ifeq ($(OS),bsd)
SEARCH_DIRS += -I/usr/local/include
OBJS = $(notdir $(patsubst %.cpp, %.o, $(patsubst %.c, %.o, $(SRCS))))
-CXXFLAGS += -Wall
-LDFLAGS += -Wl,-E -L$(DIR_LIB) -Wl,-rpath,$(PREFIX)/usr/lib/stg -Wl,-rpath-link,$(DIR_LIB)
-
-vpath %.so $(DIR_LIB)
+CXXFLAGS += $(DEFS) $(STGLIBS_INCS) $(SEARCH_DIRS)
+CFLAGS += $(DEFS) $(STGLIBS_INCS) $(SEARCH_DIRS)
+LDFLAGS += -Wl,-E $(STGLIBS_LIBS)
.PHONY: all clean distclean libs install uninstall install-bin install-data uninstall-bin uninstall-data
all: libs $(PROG) ../../Makefile.conf
libs:
$(MAKE) -C $(DIR_LIBSRC)
-$(PROG): $(OBJS) $(STGLIBS)
- $(CC) $^ $(LDFLAGS) $(LIBS) -o $(PROG)
+$(PROG): $(OBJS)
+ $(CXX) $^ $(LDFLAGS) $(LIBS) -o $(PROG)
clean:
rm -f deps $(PROG) *.o tags *.*~ .OS
endif
deps: $(SRCS) ../../Makefile.conf
- $(MAKE) -C $(DIR_LIBSRC) includes
+ $(MAKE) -C $(DIR_LIBSRC)
@>deps ;\
for file in $(SRCS); do\
- echo "`$(CC) $(CXXFLAGS) $(SEARCH_DIRS) -MM $$file` Makefile" >> deps ;\
- echo -e '\t$$(CC) -c $$< $(CXXFLAGS) $(SEARCH_DIRS) $(DEFS)' >> deps ;\
+ echo "`$(CC) $(CXXFLAGS) -MM $$file` Makefile" >> deps ;\
+ printf '%b\n' '\t$$(CC) -c $$< $(CXXFLAGS)' >> deps ;\
done
-
-
then
DEFS="-DDEBUG"
MAKEOPTS="-j1"
- CXXFLAGS="$CXXFLAGS -g3 -W -Wall"
+ CXXFLAGS="$CXXFLAGS -ggdb3 -W -Wall"
else
MAKEOPTS="-j1"
fi
then
DEFS="$DEFS -DLINUX"
LIB_THREAD=-lpthread
- SHELL="/bin/bash"
else
if [ "$OS" = "bsd" ]
then
LIB_THREAD=-lc_r
fi
fi
- SHELL="/usr/local/bin/bash"
fi
if [ -z "$CC" ]
echo -n "Checking endianess... "
echo "int main() { int probe = 0x00000001; return *(char *)&probe; }" > build_check.c
-$CC $CXXFLAGS $LDFLAGS build_check.c -o fake > /dev/null 2> /dev/null
+$CC $CFLAGS $LDFLAGS build_check.c -o fake > /dev/null 2> /dev/null
if [ $? != 0 ]
then
echo "FAIL!"
then
ARCH=le
CXXFLAGS="$CXXFLAGS -DARCH_LE"
+ CFLAGS="$CFLAGS -DARCH_LE"
echo "Little Endian"
else
ARCH=be
CXXFLAGS="$CXXFLAGS -DARCH_BE"
+ CFLAGS="$CFLAGS -DARCH_BE"
echo "Big Endian"
fi
fi
echo -n "Checking for -lexpat... "
echo "int main() { return 0; }" > build_check.c
-$CC $CXXFLAGS $LDFLAGS build_check.c -lexpat -o fake > /dev/null 2> /dev/null
+$CC $CFLAGS $LDFLAGS build_check.c -lexpat -o fake > /dev/null 2> /dev/null
if [ $? != 0 ]
then
CHECK_EXPAT=no
done
echo "" >> $CONFFILE
echo "LIB_THREAD=$LIB_THREAD" >> $CONFFILE
-echo "SHELL=$SHELL" >> $CONFFILE
echo "CXXFLAGS=$CXXFLAGS" >> $CONFFILE
+echo "CFLAGS=$CFLAGS" >> $CONFFILE
echo "LDFLAGS=$LDFLAGS" >> $CONFFILE
echo "PREFIX=$PREFIX" >> $CONFFILE
echo "BIN_MODE=$BIN_MODE" >> $CONFFILE
SRCS = ./main.cpp \
./parser.cpp
-LIBS = -lstgconffiles \
- -lstgcrypto \
- -lstgcommon \
- -lstgsrvconf
+STGLIBS = conffiles \
+ srvconf \
+ crypto \
+ common
-LIBS += -lexpat \
- $(LIB_THREAD)
+STGLIBS_INCS = $(addprefix -I ../../stglibs/,$(addsuffix .lib/include,$(STGLIBS)))
+STGLIBS_LIBS = $(addprefix -L ../../stglibs/,$(addsuffix .lib,$(STGLIBS)))
+
+LIBS += $(addprefix -lstg,$(STGLIBS)) -lexpat $(LIB_THREAD)
ifeq ($(OS),linux)
-LIBS += -ldl
else
LIBS += -lc \
-liconv
endif
-SEARCH_DIRS = -I $(DIR_INCLUDE)
+SEARCH_DIRS = -I ../../include
ifeq ($(OS),bsd)
SEARCH_DIRS += -I/usr/local/include
OBJS = $(notdir $(patsubst %.cpp, %.o, $(patsubst %.c, %.o, $(SRCS))))
-CXXFLAGS += -Wall
-LDFLAGS += -Wl,-E -L$(DIR_LIB) -Wl,-rpath,$(PREFIX)/usr/lib/stg -Wl,-rpath-link,$(DIR_LIB)
-
-vpath %.so $(DIR_LIB)
+CXXFLAGS += $(DEFS) $(STGLIBS_INCS) $(SEARCH_DIRS)
+CFLAGS += $(DEFS) $(STGLIBS_INCS) $(SEARCH_DIRS)
+LDFLAGS += -Wl,-E $(STGLIBS_LIBS)
.PHONY: all clean distclean libs install uninstall install-bin install-data uninstall-bin uninstall-data
all: libs $(PROG) ../../Makefile.conf
libs:
$(MAKE) -C $(DIR_LIBSRC)
-$(PROG): $(OBJS) $(STGLIBS)
- $(CC) $^ $(LIBS) $(LDFLAGS) -o $(PROG)
+$(PROG): $(OBJS)
+ $(CXX) $^ $(LIBS) $(LDFLAGS) -o $(PROG)
clean:
rm -f deps $(PROG) *.o tags *.*~ .OS
endif
deps: $(SRCS) ../../Makefile.conf
- $(MAKE) -C $(DIR_LIBSRC) includes
+ $(MAKE) -C $(DIR_LIBSRC)
@>deps ;\
for file in $(SRCS); do\
- echo "`$(CC) $(CXXFLAGS) $(SEARCH_DIRS) -MM $$file` Makefile" >> deps ;\
- echo -e '\t$$(CC) -c $$< $(CXXFLAGS) $(SEARCH_DIRS) $(DEFS)' >> deps ;\
+ echo "`$(CC) $(CXXFLAGS) -MM $$file` Makefile" >> deps ;\
+ printf '%b\n' '\t$$(CC) -c $$< $(CXXFLAGS)' >> deps ;\
done
-
-
then
DEFS="-DDEBUG"
MAKEOPTS="-j1"
- CXXFLAGS="$CXXFLAGS -g3 -W -Wall"
+ CXXFLAGS="$CXXFLAGS -ggdb3 -W -Wall"
else
MAKEOPTS="-j1"
fi
then
DEFS="$DEFS -DLINUX"
LIB_THREAD=-lpthread
- SHELL="/bin/bash"
else
if [ "$OS" = "bsd" ]
then
LIB_THREAD=-lc_r
fi
fi
- SHELL="/usr/local/bin/bash"
fi
if [ -z "$CC" ]
echo -n "Checking endianess... "
echo "int main() { int probe = 0x00000001; return *(char *)&probe; }" > build_check.c
-$CC $CXXFLAGS $LDFLAGS build_check.c -o fake > /dev/null 2> /dev/null
+$CC $CFLAGS $LDFLAGS build_check.c -o fake > /dev/null 2> /dev/null
if [ $? != 0 ]
then
echo "FAIL!"
then
ARCH=le
CXXFLAGS="$CXXFLAGS -DARCH_LE"
+ CFLAGS="$CFLAGS -DARCH_LE"
echo "Little Endian"
else
ARCH=be
CXXFLAGS="$CXXFLAGS -DARCH_BE"
+ CFLAGS="$CFLAGS -DARCH_BE"
echo "Big Endian"
fi
fi
done
echo "" >> $CONFFILE
echo "LIB_THREAD=$LIB_THREAD" >> $CONFFILE
-echo "SHELL=$SHELL" >> $CONFFILE
echo "CXXFLAGS=$CXXFLAGS" >> $CONFFILE
+echo "CFLAGS=$CFLAGS" >> $CONFFILE
echo "LDFLAGS=$LDFLAGS" >> $CONFFILE
echo "PREFIX=$PREFIX" >> $CONFFILE
echo "BIN_MODE=$BIN_MODE" >> $CONFFILE
SRCS = ./admin_impl.cpp \
./admins_impl.cpp \
+ ./corps_impl.cpp \
./eventloop.cpp \
./main.cpp \
./pidfile.cpp \
./plugin_runner.cpp \
./settings_impl.cpp \
+ ./services_impl.cpp \
./stg_timer.cpp \
./store_loader.cpp \
./tariff_impl.cpp \
./user_property.cpp \
./users_impl.cpp
-STGLIBS = -lstglogger \
- -lstglocker \
- -lstgcommon \
- -lstgscriptexecuter \
- -ldotconfpp
+STGLIBS = scriptexecuter \
+ dotconfpp \
+ locker \
+ logger \
+ common
-LIBS += -lexpat
+STGLIBS_INCS = $(addprefix -I ../../stglibs/,$(addsuffix .lib/include,$(STGLIBS)))
+STGLIBS_LIBS = $(addprefix -L ../../stglibs/,$(addsuffix .lib,$(STGLIBS)))
+
+LIBS += $(addprefix -lstg,$(STGLIBS)) $(LIB_THREAD)
ifeq ($(OS),linux)
-LIBS += $(LIB_THREAD) \
- -ldl
+LIBS += -ldl
else
-LIBS += $(LIB_THREAD) \
- -lc
+LIBS += -lc -liconv
endif
-SEARCH_DIRS = -I $(DIR_INCLUDE)
+SEARCH_DIRS = -I ../../include
OBJS = $(notdir $(patsubst %.cpp, %.o, $(patsubst %.c, %.o, $(SRCS))))
-LDFLAGS += -Wl,-E -L$(DIR_LIB) -Wl,-rpath,$(PREFIX)/usr/lib/stg -Wl,-rpath-link,$(DIR_LIB)
-vpath %.so $(DIR_LIB)
+CXXFLAGS += $(DEFS) $(STGLIBS_INCS) $(SEARCH_DIRS)
+CFLAGS += $(DEFS) $(STGLIBS_INCS) $(SEARCH_DIRS)
+LDFLAGS += -Wl,-E $(STGLIBS_LIBS)
.PHONY: all clean distclean libs plugins install uninstall install-bin install-data
all: libs plugins $(PROG)
plugins: libs
$(MAKE) -C $(DIR_PLUGINS)
-$(PROG): $(OBJS) libs
- $(CXX) $(OBJS) $(LDFLAGS) $(LIBS) $(STGLIBS) -o $(PROG)
+$(PROG): $(OBJS)
+ $(CXX) $^ $(LDFLAGS) $(LIBS) -o $(PROG)
clean:
rm -f deps $(PROG) *.o tags *.*~ .OS
mkdir -m $(DIR_MODE) -p $(PREFIX)/etc/stargazer/conf-enabled.d
install -m $(DATA_MODE) -o $(OWNER) $(ETC_DIR)/stargazer.conf $(PREFIX)/etc/stargazer/stargazer.conf
install -m $(DATA_MODE) -o $(OWNER) $(ETC_DIR)/conf-available.d/*.conf $(PREFIX)/etc/stargazer/conf-available.d
- ln -s ../conf-available.d/mod_ao.conf $(PREFIX)/etc/stargazer/conf-enabled.d/mod_ao.conf
- ln -s ../conf-available.d/mod_ia.conf $(PREFIX)/etc/stargazer/conf-enabled.d/mod_ia.conf
- ln -s ../conf-available.d/mod_ping.conf $(PREFIX)/etc/stargazer/conf-enabled.d/mod_ping.conf
- ln -s ../conf-available.d/mod_sg.conf $(PREFIX)/etc/stargazer/conf-enabled.d/mod_sg.conf
+ ln -sf ../conf-available.d/mod_ao.conf $(PREFIX)/etc/stargazer/conf-enabled.d/mod_ao.conf
+ ln -sf ../conf-available.d/mod_ia.conf $(PREFIX)/etc/stargazer/conf-enabled.d/mod_ia.conf
+ ln -sf ../conf-available.d/mod_ping.conf $(PREFIX)/etc/stargazer/conf-enabled.d/mod_ping.conf
+ ln -sf ../conf-available.d/mod_sg.conf $(PREFIX)/etc/stargazer/conf-enabled.d/mod_sg.conf
ifeq ($(OS),linux)
- ln -s ../conf-available.d/mod_cap_ether.conf $(PREFIX)/etc/stargazer/conf-enabled.d/mod_cap_ether.conf
+ ln -sf ../conf-available.d/mod_cap_ether.conf $(PREFIX)/etc/stargazer/conf-enabled.d/mod_cap_ether.conf
else
- ln -s ../conf-available.d/mod_cap_bpf.conf $(PREFIX)/etc/stargazer/conf-enabled.d/mod_cap_bpf.conf
+ ln -sf ../conf-available.d/mod_cap_bpf.conf $(PREFIX)/etc/stargazer/conf-enabled.d/mod_cap_bpf.conf
endif
install -m $(DATA_MODE) -o $(OWNER) $(ETC_DIR)/rules $(PREFIX)/etc/stargazer/rules
install -m $(DATA_MODE) -o $(OWNER) $(VAR_DIR)/tariffs/tariff.tf $(PREFIX)/var/stargazer/tariffs/tariff.tf
install -m $(DATA_MODE) -o $(OWNER) $(VAR_DIR)/users/test/conf $(PREFIX)/var/stargazer/users/test/conf
install -m $(DATA_MODE) -o $(OWNER) $(VAR_DIR)/users/test/stat $(PREFIX)/var/stargazer/users/test/stat
-
-ifeq ($(CHECK_FBCLIENT),yes)
- # Install firebird db
- mkdir -p $(PREFIX)/var/stargazer
- chown $(OWNER):$(FIREBIRD_GROUP) $(PREFIX)/var/stargazer
- chmod g+rw $(PREFIX)/var/stargazer
- echo "connect '$(DB_ADDRESS)' user '$(DB_USER)' password '$(DB_PASSWORD)';" > .db.sql
- echo "drop database;" >> .db.sql
- echo "create database '$(DB_ADDRESS)' user '$(DB_USER)' password '$(DB_PASSWORD)' default character set win1251;" >> .db.sql
- cat $(VAR_DIR)/../00-base-00.sql >> .db.sql
- $(FIREBIRD_ISQL) -i .db.sql
- rm -f .db.sql
-endif
uninstall: uninstall-bin uninstall-data
endif
deps: $(SRCS) ../../Makefile.conf
- $(MAKE) -C $(DIR_LIBSRC) includes
+ $(MAKE) -C $(DIR_LIBSRC)
@>deps ;\
for file in $(SRCS); do\
- echo "`$(CC) $(CXXFLAGS) $(SEARCH_DIRS) -MM $$file` Makefile ../../Makefile.conf" >> deps ;\
- echo -e '\t$$(CC) -c $$< $(CXXFLAGS) $(SEARCH_DIRS) $(DEFS)' >> deps ;\
+ echo "`$(CC) $(CXXFLAGS) -MM $$file` Makefile ../../Makefile.conf" >> deps ;\
+ printf '%b\n' '\t$$(CC) -c $$< $(CXXFLAGS)' >> deps ;\
done
class BASE_ACTION
{
public:
- virtual ~BASE_ACTION() {};
+ virtual ~BASE_ACTION() {}
virtual void Invoke() = 0;
};
: activeClass(ac), actor(a), data(d) {};
void Invoke();
private:
+ ACTION(const ACTION<ACTIVE_CLASS, DATA_TYPE> & rvalue);
+ ACTION<ACTIVE_CLASS, DATA_TYPE> & operator=(const ACTION<ACTIVE_CLASS, DATA_TYPE> & rvalue);
+
ACTIVE_CLASS & activeClass;
typename ACTOR<ACTIVE_CLASS, DATA_TYPE>::TYPE actor;
DATA_TYPE data;
// Initialize mutex
ACTIONS_LIST();
// Delete actions and destroy mutex
- ~ACTIONS_LIST();
+ virtual ~ACTIONS_LIST();
parent::iterator begin();
parent::iterator end();
: mutex()
{
pthread_mutex_init(&mutex, NULL);
-};
+}
// Delete all actions before deleting list
inline
}
pthread_mutex_destroy(&mutex);
-};
+}
inline
ACTIONS_LIST::parent::iterator ACTIONS_LIST::begin()
{
STG_LOCKER lock(&mutex, __FILE__, __LINE__);
return parent::begin();
-};
+}
inline
ACTIONS_LIST::parent::iterator ACTIONS_LIST::end()
{
STG_LOCKER lock(&mutex, __FILE__, __LINE__);
return parent::end();
-};
+}
inline
ACTIONS_LIST::parent::const_iterator ACTIONS_LIST::begin() const
{
STG_LOCKER lock(&mutex, __FILE__, __LINE__);
return parent::begin();
-};
+}
inline
ACTIONS_LIST::parent::const_iterator ACTIONS_LIST::end() const
{
STG_LOCKER lock(&mutex, __FILE__, __LINE__);
return parent::end();
-};
+}
inline
bool ACTIONS_LIST::empty() const
{
STG_LOCKER lock(&mutex, __FILE__, __LINE__);
return parent::empty();
-};
+}
inline
size_t ACTIONS_LIST::size() const
{
STG_LOCKER lock(&mutex, __FILE__, __LINE__);
return parent::size();
-};
+}
inline
void ACTIONS_LIST::swap(ACTIONS_LIST & list)
{
STG_LOCKER lock(&mutex, __FILE__, __LINE__);
parent::swap(list);
-};
+}
template <class ACTIVE_CLASS, typename DATA_TYPE>
inline
parent::end(),
std::mem_fun(&BASE_ACTION::Invoke)
);
-};
+}
#endif
{
}
//-----------------------------------------------------------------------------
-ADMIN & ADMIN_IMPL::operator=(const ADMIN & adm)
+ADMIN_IMPL & ADMIN_IMPL::operator=(const ADMIN_IMPL & adm)
{
if (&adm == this)
return *this;
-conf = adm.GetConf();
-ip = adm.GetIP();
+conf = adm.conf;
+ip = adm.ip;
return *this;
}
//-----------------------------------------------------------------------------
-ADMIN & ADMIN_IMPL::operator=(const ADMIN_CONF & ac)
+ADMIN_IMPL & ADMIN_IMPL::operator=(const ADMIN_CONF & ac)
{
conf = ac;
return *this;
}
//-----------------------------------------------------------------------------
-bool ADMIN_IMPL::operator==(const ADMIN & rhs) const
+bool ADMIN_IMPL::operator==(const ADMIN_IMPL & rhs) const
{
-return conf.login == rhs.GetLogin();
+return conf.login == rhs.conf.login;
}
//-----------------------------------------------------------------------------
-bool ADMIN_IMPL::operator!=(const ADMIN & rhs) const
+bool ADMIN_IMPL::operator!=(const ADMIN_IMPL & rhs) const
{
-return conf.login != rhs.GetLogin();
+return conf.login != rhs.conf.login;
}
//-----------------------------------------------------------------------------
-bool ADMIN_IMPL::operator<(const ADMIN & rhs) const
+bool ADMIN_IMPL::operator<(const ADMIN_IMPL & rhs) const
{
-return conf.login < rhs.GetLogin();
+return conf.login < rhs.conf.login;
}
//-----------------------------------------------------------------------------
-bool ADMIN_IMPL::operator<=(const ADMIN & rhs) const
+bool ADMIN_IMPL::operator<=(const ADMIN_IMPL & rhs) const
{
-return conf.login <= rhs.GetLogin();
+return conf.login <= rhs.conf.login;
}
//-----------------------------------------------------------------------------
std::string ADMIN_IMPL::GetIPStr() const
const std::string & password);
virtual ~ADMIN_IMPL() {};
- ADMIN & operator=(const ADMIN &);
- ADMIN & operator=(const ADMIN_CONF &);
- bool operator==(const ADMIN & rhs) const;
- bool operator!=(const ADMIN & rhs) const;
- bool operator<(const ADMIN & rhs) const;
- bool operator<=(const ADMIN & rhs) const;
+ ADMIN_IMPL & operator=(const ADMIN_IMPL &);
+ ADMIN_IMPL & operator=(const ADMIN_CONF &);
+ bool operator==(const ADMIN_IMPL & rhs) const;
+ bool operator!=(const ADMIN_IMPL & rhs) const;
+ bool operator<(const ADMIN_IMPL & rhs) const;
+ bool operator<=(const ADMIN_IMPL & rhs) const;
const std::string & GetPassword() const { return conf.password; };
const std::string & GetLogin() const { return conf.login; };
#include <cassert>
#include <algorithm>
-#include "stg/admins.h"
-#include "stg/admin.h"
#include "stg/common.h"
#include "admins_impl.h"
#include "admin_impl.h"
store(st),
WriteServLog(GetStgLogger()),
searchDescriptors(),
- handle(0)
+ handle(0),
+ mutex(),
+ strError()
{
pthread_mutex_init(&mutex, NULL);
-ReadAdmins();
+Read();
}
//-----------------------------------------------------------------------------
int ADMINS_IMPL::Add(const string & login, const ADMIN * admin)
return 0;
}
//-----------------------------------------------------------------------------
-int ADMINS_IMPL::ReadAdmins()
+int ADMINS_IMPL::Read()
{
STG_LOCKER lock(&mutex, __FILE__, __LINE__);
vector<string> adminsList;
}
}
//-----------------------------------------------------------------------------
-bool ADMINS_IMPL::FindAdmin(const string & l, ADMIN ** admin)
+bool ADMINS_IMPL::Find(const string & l, ADMIN ** admin)
{
assert(admin != NULL && "Pointer to admin is not null");
return true;
}
//-----------------------------------------------------------------------------
-bool ADMINS_IMPL::AdminExists(const string & login) const
+bool ADMINS_IMPL::Exists(const string & login) const
{
STG_LOCKER lock(&mutex, __FILE__, __LINE__);
if (data.empty())
return false;
}
//-----------------------------------------------------------------------------
-bool ADMINS_IMPL::AdminCorrect(const string & login, const std::string & password, ADMIN ** admin)
+bool ADMINS_IMPL::Correct(const string & login, const std::string & password, ADMIN ** admin)
{
STG_LOCKER lock(&mutex, __FILE__, __LINE__);
if (data.empty())
#include <list>
#include <map>
+#include <string>
#include "stg/admins.h"
#include "stg/admin.h"
#include "stg/locker.h"
#include "stg/store.h"
#include "stg/noncopyable.h"
+#include "stg/logger.h"
#include "admin_impl.h"
class ADMINS_IMPL : private NONCOPYABLE, public ADMINS {
ADMINS_IMPL(STORE * st);
virtual ~ADMINS_IMPL() {}
- int Add(const string & login, const ADMIN * admin);
- int Del(const string & login, const ADMIN * admin);
+ int Add(const std::string & login, const ADMIN * admin);
+ int Del(const std::string & login, const ADMIN * admin);
int Change(const ADMIN_CONF & ac, const ADMIN * admin);
void PrintAdmins() const;
const ADMIN * GetSysAdmin() const { return &stg; }
const ADMIN * GetNoAdmin() const { return &noAdmin; }
- bool FindAdmin(const std::string & l, ADMIN ** admin);
- bool AdminExists(const std::string & login) const;
- bool AdminCorrect(const std::string & login,
- const std::string & password,
- ADMIN ** admin);
+ bool Find(const std::string & l, ADMIN ** admin);
+ bool Exists(const std::string & login) const;
+ bool Correct(const std::string & login,
+ const std::string & password,
+ ADMIN ** admin);
const std::string & GetStrError() const { return strError; }
+ size_t Count() const { return data.size(); }
+
int OpenSearch() const;
int SearchNext(int, ADMIN_CONF * ac) const;
int CloseSearch(int) const;
private:
+ ADMINS_IMPL(const ADMINS_IMPL & rvalue);
+ ADMINS_IMPL & operator=(const ADMINS_IMPL & rvalue);
+
typedef list<ADMIN_IMPL>::iterator admin_iter;
typedef list<ADMIN_IMPL>::const_iterator const_admin_iter;
- int ReadAdmins();
+ int Read();
- ADMIN_IMPL stg;
- ADMIN_IMPL noAdmin;
- list<ADMIN_IMPL> data;
- STORE * store;
- STG_LOGGER & WriteServLog;
- mutable map<int, const_admin_iter> searchDescriptors;
- mutable unsigned int handle;
+ ADMIN_IMPL stg;
+ ADMIN_IMPL noAdmin;
+ std::list<ADMIN_IMPL> data;
+ STORE * store;
+ STG_LOGGER & WriteServLog;
+ mutable std::map<int, const_admin_iter> searchDescriptors;
+ mutable unsigned int handle;
mutable pthread_mutex_t mutex;
- std::string strError;
+ std::string strError;
};
#endif
OWNER=root
-# Name of the firebird's group
-# Need for chown directory with firebird db
-
-FIREBIRD_GROUP=firebird
-
-# Database address
-# Firebird must have priviledges to read/write for specified path
-
-DB_ADDRESS="localhost:/var/stargazer/stargazer.fdb"
-
-# Database user
-# This user must have priviledges to create database
-
-DB_USER="stg"
-
-# Database password
-
-DB_PASSWORD="123456"
-
-# Full path to isql utility
-# Note: Debian users have to specify path to isql-fb utility
-
-FIREBIRD_ISQL="/opt/firebird/bin/isql"
-
OS=unknown
sys=`uname -s`
release=`uname -r | cut -b1`
then
DEFS="$DEFS -DDEBUG"
MAKEOPTS="-j1"
- CXXFLAGS="$CXXFLAGS -g3 -W -Wall"
+ CXXFLAGS="$CXXFLAGS -ggdb3 -W -Wall"
else
DEFS="$DEFS -DNDEBUG"
MAKEOPTS="-j1"
scriptexecuter.lib
conffiles.lib
pinger.lib
- dotconfpp.lib"
+ dotconfpp.lib
+ smux.lib"
PLUGINS="authorization/ao
authorization/inetaccess
other/ping
other/rscript
other/radius
+ other/smux
store/files
capture/cap_nf"
PLUGINS="$PLUGINS
capture/ether_linux
capture/ipq_linux"
- SHELL="/bin/bash"
LIB_THREAD=-lpthread
else
if [ "$OS" = "bsd" ]
PLUGINS="$PLUGINS
capture/ether_freebsd
capture/divert_freebsd"
- SHELL="/usr/local/bin/bash"
fi
if [ -z "$CC" ]
echo -n "Checking endianess... "
echo "int main() { int probe = 0x00000001; return *(char *)&probe; }" > build_check.c
-$CC $CXXFLAGS $LDFLAGS build_check.c -o fake
+$CC $CFLAGS $LDFLAGS build_check.c -o fake
if [ $? != 0 ]
then
echo "FAIL!"
then
ARCH=le
CXXFLAGS="$CXXFLAGS -DARCH_LE"
+ CFLAGS="$CFLAGS -DARCH_LE"
echo "Little Endian"
else
ARCH=be
CXXFLAGS="$CXXFLAGS -DARCH_BE"
+ CFLAGS="$CFLAGS -DARCH_BE"
echo "Big Endian"
fi
fi
echo -n "Checking for -lexpat... "
echo "int main() { return 0; }" > build_check.c
-$CC $CXXFLAGS $LDFLAGS build_check.c -lexpat -o fake > /dev/null 2> /dev/null
+$CC $CFLAGS $LDFLAGS build_check.c -lexpat -o fake > /dev/null 2> /dev/null
if [ $? != 0 ]
then
CHECK_EXPAT=no
rm -f fake
echo -n "Checking for -lfbclient... "
-$CC $CXXFLAGS $LDFLAGS build_check.c -lfbclient $LIB_THREAD -o fake > /dev/null 2> /dev/null
+$CC $CFLAGS $LDFLAGS build_check.c -lfbclient $LIB_THREAD -o fake > /dev/null 2> /dev/null
if [ $? != 0 ]
then
CHECK_FBCLIENT=no
then
echo "no";
echo -n "Checking for -lmysqlclient... "
- $CC $CXXFLAGS $LDFLAGS build_check.c -lmysqlclient_r $LIB_THREAD -o fake > /dev/null 2> /dev/null
+ $CC $CFLAGS $LDFLAGS build_check.c -lmysqlclient_r $LIB_THREAD -o fake > /dev/null 2> /dev/null
if [ $? != 0 ]
then
CHECK_MYSQLCLIENT=no
CHECK_MYSQLCLIENT=no
echo "no"
else
- #CXXFLAGS="$CXXFLAGS $MYSQL_CFLAGS"
echo "[$MYSQL_CFLAGS]"
echo -n "Checking for mysql_config --libs_r... "
MYSQL_LDFLAGS=`mysql_config --libs_r 2> /dev/null`
echo "no"
else
CHECK_MYSQLCLIENT=yes
- #LDFLAGS="$LDFLAGS $MYSQL_LDFLAGS"
echo "[$MYSQL_LDFLAGS]"
fi
fi
then
echo "no";
echo -n "Checking for -lpq... "
- $CC $CXXFLAGS $LDFLAGS build_check.c -lpq $LIB_THREAD -o fake > /dev/null 2> /dev/null
+ $CC $CFLAGS $LDFLAGS build_check.c -lpq $LIB_THREAD -o fake > /dev/null 2> /dev/null
if [ $? != 0 ]
then
CHECK_PQ=no
then
echo "no";
echo -n "Checking for -lxmlrpc... "
- $CC $CXXFLAGS $LDFLAGS build_check.c -lxmlrpc $LIB_THREAD -o fake > /dev/null 2> /dev/null
+ $CC $CFLAGS $LDFLAGS build_check.c -lxmlrpc $LIB_THREAD -o fake > /dev/null 2> /dev/null
if [ $? != 0 ]
then
CHECK_XMLRPC=no
echo -n "$plugin " >> $CONFFILE
done
echo "" >> $CONFFILE
-echo "SHELL=$SHELL" >> $CONFFILE
echo "CXXFLAGS=$CXXFLAGS" >> $CONFFILE
+echo "CFLAGS=$CFLAGS" >> $CONFFILE
echo "LDFLAGS=$LDFLAGS" >> $CONFFILE
echo "LIB_THREAD=$LIB_THREAD" >> $CONFFILE
echo "PREFIX=$PREFIX" >> $CONFFILE
echo "OWNER=$OWNER" >> $CONFFILE
echo "VAR_DIR=$VAR_DIR" >> $CONFFILE
echo "ETC_DIR=$ETC_DIR" >> $CONFFILE
-echo "DB_ADDRESS=$DB_ADDRESS" >> $CONFFILE
-echo "DB_USER=$DB_USER" >> $CONFFILE
-echo "DB_PASSWORD=$DB_PASSWORD" >> $CONFFILE
-echo "FIREBIRD_ISQL=$FIREBIRD_ISQL" >> $CONFFILE
-echo "FIREBIRD_GROUP=$FIREBIRD_GROUP" >> $CONFFILE
mkdir -p modules
--- /dev/null
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Author : Maxim Mamontov <faust@stargazer.dp.ua>
+ */
+
+#include <cerrno>
+#include <cassert>
+#include <algorithm>
+
+#include "stg/admin.h"
+#include "stg/common.h"
+#include "corps_impl.h"
+
+//-----------------------------------------------------------------------------
+CORPORATIONS_IMPL::CORPORATIONS_IMPL(STORE * st)
+ : CORPORATIONS(),
+ data(),
+ store(st),
+ WriteServLog(GetStgLogger()),
+ searchDescriptors(),
+ handle(0),
+ mutex(),
+ strError()
+{
+pthread_mutex_init(&mutex, NULL);
+Read();
+}
+//-----------------------------------------------------------------------------
+int CORPORATIONS_IMPL::Add(const CORP_CONF & corp, const ADMIN * admin)
+{
+STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+const PRIV * priv = admin->GetPriv();
+
+if (!priv->corpChg)
+ {
+ string s = admin->GetLogStr() + " Add corporation \'" + corp.name + "\'. Access denied.";
+ strError = "Access denied.";
+ WriteServLog(s.c_str());
+ return -1;
+ }
+
+crp_iter si(find(data.begin(), data.end(), corp));
+
+if (si != data.end())
+ {
+ strError = "Corporation \'" + corp.name + "\' cannot not be added. Corporation already exist.";
+ WriteServLog("%s %s", admin->GetLogStr().c_str(), strError.c_str());
+
+ return -1;
+ }
+
+data.push_back(corp);
+
+if (store->AddCorp(corp.name) == 0)
+ {
+ WriteServLog("%s Corporation \'%s\' added.",
+ admin->GetLogStr().c_str(), corp.name.c_str());
+ return 0;
+ }
+
+strError = "Corporation \'" + corp.name + "\' was not added. Error: " + store->GetStrError();
+WriteServLog("%s %s", admin->GetLogStr().c_str(), strError.c_str());
+
+return -1;
+}
+//-----------------------------------------------------------------------------
+int CORPORATIONS_IMPL::Del(const string & name, const ADMIN * admin)
+{
+STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+const PRIV * priv = admin->GetPriv();
+
+if (!priv->corpChg)
+ {
+ string s = admin->GetLogStr() + " Delete corporation \'" + name + "\'. Access denied.";
+ strError = "Access denied.";
+ WriteServLog(s.c_str());
+ return -1;
+ }
+
+crp_iter si(find(data.begin(), data.end(), CORP_CONF(name)));
+
+if (si == data.end())
+ {
+ strError = "Corporation \'" + name + "\' cannot be deleted. Corporation does not exist.";
+ WriteServLog("%s %s", admin->GetLogStr().c_str(), strError.c_str());
+ return -1;
+ }
+
+map<int, const_crp_iter>::iterator csi;
+csi = searchDescriptors.begin();
+while (csi != searchDescriptors.end())
+ {
+ if (csi->second == si)
+ (csi->second)++;
+ csi++;
+ }
+
+data.remove(*si);
+if (store->DelCorp(name) < 0)
+ {
+ strError = "Corporation \'" + name + "\' was not deleted. Error: " + store->GetStrError();
+ WriteServLog("%s %s", admin->GetLogStr().c_str(), strError.c_str());
+
+ return -1;
+ }
+
+WriteServLog("%s Corporation \'%s\' deleted.", admin->GetLogStr().c_str(), name.c_str());
+return 0;
+}
+//-----------------------------------------------------------------------------
+int CORPORATIONS_IMPL::Change(const CORP_CONF & corp, const ADMIN * admin)
+{
+STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+const PRIV * priv = admin->GetPriv();
+
+if (!priv->corpChg)
+ {
+ string s = admin->GetLogStr() + " Change corporation \'" + corp.name + "\'. Access denied.";
+ strError = "Access denied.";
+ WriteServLog(s.c_str());
+ return -1;
+ }
+
+crp_iter si(find(data.begin(), data.end(), corp));
+
+if (si == data.end())
+ {
+ strError = "Corporation \'" + corp.name + "\' cannot be changed " + ". Corporation does not exist.";
+ WriteServLog("%s %s", admin->GetLogStr().c_str(), strError.c_str());
+ return -1;
+ }
+
+*si = corp;
+if (store->SaveCorp(corp))
+ {
+ WriteServLog("Cannot write corporation %s.", corp.name.c_str());
+ WriteServLog("%s", store->GetStrError().c_str());
+ return -1;
+ }
+
+WriteServLog("%s Corporation \'%s\' changed.",
+ admin->GetLogStr().c_str(), corp.name.c_str());
+
+return 0;
+}
+//-----------------------------------------------------------------------------
+bool CORPORATIONS_IMPL::Read()
+{
+STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+vector<string> corpsList;
+if (store->GetCorpsList(&corpsList) < 0)
+ {
+ WriteServLog(store->GetStrError().c_str());
+ return true;
+ }
+
+for (size_t i = 0; i < corpsList.size(); i++)
+ {
+ CORP_CONF corp;
+
+ if (store->RestoreCorp(&corp, corpsList[i]))
+ {
+ WriteServLog(store->GetStrError().c_str());
+ return true;
+ }
+
+ data.push_back(corp);
+ }
+return false;
+}
+//-----------------------------------------------------------------------------
+bool CORPORATIONS_IMPL::Find(const string & name, CORP_CONF * corp)
+{
+assert(corp != NULL && "Pointer to corporation is not null");
+
+STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+if (data.empty())
+ return false;
+
+crp_iter si(find(data.begin(), data.end(), CORP_CONF(name)));
+
+if (si != data.end())
+ {
+ *corp = *si;
+ return false;
+ }
+
+return true;
+}
+//-----------------------------------------------------------------------------
+bool CORPORATIONS_IMPL::Exists(const string & name) const
+{
+STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+if (data.empty())
+ {
+ printfd(__FILE__, "no admin in system!\n");
+ return true;
+ }
+
+const_crp_iter si(find(data.begin(), data.end(), CORP_CONF(name)));
+
+if (si != data.end())
+ return true;
+
+return false;
+}
+//-----------------------------------------------------------------------------
+int CORPORATIONS_IMPL::OpenSearch() const
+{
+STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+handle++;
+searchDescriptors[handle] = data.begin();
+return handle;
+}
+//-----------------------------------------------------------------------------
+int CORPORATIONS_IMPL::SearchNext(int h, CORP_CONF * corp) const
+{
+STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+if (searchDescriptors.find(h) == searchDescriptors.end())
+ {
+ WriteServLog("CORPORATIONS. Incorrect search handle.");
+ return -1;
+ }
+
+if (searchDescriptors[h] == data.end())
+ return -1;
+
+*corp = *searchDescriptors[h]++;
+
+return 0;
+}
+//-----------------------------------------------------------------------------
+int CORPORATIONS_IMPL::CloseSearch(int h) const
+{
+STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+if (searchDescriptors.find(h) != searchDescriptors.end())
+ {
+ searchDescriptors.erase(searchDescriptors.find(h));
+ return 0;
+ }
+
+WriteServLog("CORPORATIONS. Incorrect search handle.");
+return -1;
+}
+//-----------------------------------------------------------------------------
--- /dev/null
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Author : Maxim Mamontov <faust@stargazer.dp.ua>
+ */
+
+#ifndef CORPORATIONS_IMPL_H
+#define CORPORATIONS_IMPL_H
+
+#include <pthread.h>
+
+#include <list>
+#include <map>
+#include <string>
+
+#include "stg/corporations.h"
+#include "stg/corp_conf.h"
+#include "stg/locker.h"
+#include "stg/store.h"
+#include "stg/noncopyable.h"
+#include "stg/logger.h"
+
+class ADMIN;
+
+class CORPORATIONS_IMPL : private NONCOPYABLE, public CORPORATIONS {
+public:
+ CORPORATIONS_IMPL(STORE * st);
+ virtual ~CORPORATIONS_IMPL() {}
+
+ int Add(const CORP_CONF & corp, const ADMIN * admin);
+ int Del(const std::string & name, const ADMIN * admin);
+ int Change(const CORP_CONF & corp, const ADMIN * admin);
+ bool Find(const std::string & name, CORP_CONF * corp);
+ bool Exists(const std::string & name) const;
+ const std::string & GetStrError() const { return strError; }
+
+ size_t Count() const { return data.size(); }
+
+ int OpenSearch() const;
+ int SearchNext(int, CORP_CONF * corp) const;
+ int CloseSearch(int) const;
+
+private:
+ CORPORATIONS_IMPL(const CORPORATIONS_IMPL & rvalue);
+ CORPORATIONS_IMPL & operator=(const CORPORATIONS_IMPL & rvalue);
+
+ typedef list<CORP_CONF>::iterator crp_iter;
+ typedef list<CORP_CONF>::const_iterator const_crp_iter;
+
+ bool Read();
+
+ std::list<CORP_CONF> data;
+ STORE * store;
+ STG_LOGGER & WriteServLog;
+ mutable std::map<int, const_crp_iter> searchDescriptors;
+ mutable unsigned int handle;
+ mutable pthread_mutex_t mutex;
+ std::string strError;
+};
+
+#endif
+#include <csignal>
#include <cerrno>
#include <cstring>
#include "eventloop.h"
EVENT_LOOP::EVENT_LOOP()
- : ACTIONS_LIST()
+ : ACTIONS_LIST(),
+ _running(false),
+ _stopped(true),
+ _tid(),
+ _mutex(),
+ _condition()
{
pthread_mutex_init(&_mutex, NULL);
pthread_cond_init(&_condition, NULL);
void EVENT_LOOP::Runner()
{
+sigset_t signalSet;
+sigfillset(&signalSet);
+pthread_sigmask(SIG_BLOCK, &signalSet, NULL);
+
_stopped = false;
printfd(__FILE__, "EVENT_LOOP::Runner - Before start\n");
while (_running)
ID=$4
#Selected dirs to disconnect
-DIRS=$4
+DIRS=$5
#echo "D `date +%Y.%m.%d-%H.%M.%S` $IP $CASH" >> /var/stargazer/users/$LOGIN/connect.log
-
-
-
-
-
--- /dev/null
+<Module smux>
+ # IP-address of a server to connect to
+ # Parameter: required
+ # Value: X.X.X.X
+ # Default: 127.0.0.1
+ Server = 127.0.0.1
+
+ # Port number on a server to connect to
+ # Parameter: required
+ # Value: 1 ... 65535
+ # Default: 199
+ Port = 199
+
+ # Password for authentication on a server
+ # Parameter: optional
+ #
+ # Password = 123456
+</Module>
# Values: any, supported by OS
ConfOwner = root
ConfGroup = root
- ConfMode = 600
+ ConfMode = 640
# Owner, group and permissions on user configuration files (conf)
# Parameter: required
#MonitorDir=/var/stargazer/monitor
# Defines message maximum lifetime
-# Note: 0 — unlimited
+# Note: 0 - unlimited
# Parameter: optional
# Value: any numeric
# Default: 0 (day)
# 1 - disallow fee charge if cash value is negative;
# 2 - disallow fee charge if there is not enought cash (cash < fee).
# Parameter: optional
-# Value: 0 - 2
+# Value: 0 ... 2
# Default: 0 (classic)
# FeeChargeType = 0
ID=$4
#Selected dirs to disconnect
-DIRS=$4
+DIRS=$5
#echo "D `date +%Y.%m.%d-%H.%M.%S` $IP $CASH" >> /var/stargazer/users/$LOGIN/connect.log
-
-
-
-
-
--- /dev/null
+<Module smux>
+ # IP-address of a server to connect to
+ # Parameter: required
+ # Value: X.X.X.X
+ # Default: 127.0.0.1
+ Server = 127.0.0.1
+
+ # Port number on a server to connect to
+ # Parameter: required
+ # Value: 1 ... 65535
+ # Default: 199
+ Port = 199
+
+ # Password for authentication on a server
+ # Parameter: optional
+ #
+ # Password = 123456
+</Module>
# Values: any, supported by OS
ConfOwner = root
ConfGroup = root
- ConfMode = 600
+ ConfMode = 640
# Owner, group and permissions on user configuration files (conf)
# Parameter: required
#MonitorDir=/var/stargazer/monitor
# Defines message maximum lifetime
-# Note: 0 — unlimited
+# Note: 0 - unlimited
# Parameter: optional
# Value: any numeric
# Default: 0 (day)
# 1 - disallow fee charge if cash value is negative;
# 2 - disallow fee charge if there is not enought cash (cash < fee).
# Parameter: optional
-# Value: 0 - 2
+# Value: 0 ... 2
# Default: 0 (classic)
# FeeChargeType = 0
* 1 - down - считается по download
* 2 - max - считается по максимальному среди upload/download
* 3 - up+down - считается по сумме upload и download
- * Как альтернативу этому полю можно сделать еще одну таблицу - типов
- * подсчета трафика. И в этом поле хранить ссылку на эту таблицу.
- * Вопрос только "А надо ли это?"
*
* * dm_ip. IP адресс в виде четырех байтового целого числа со знаком.
* Выполнять приведение к знаковуму целому при занесении IP в БД!!!
CREATE DOMAIN dm_user_name AS VARCHAR(256) DEFAULT '';
CREATE DOMAIN dm_service_comment AS VARCHAR(256) DEFAULT '';
CREATE DOMAIN dm_service_name AS VARCHAR(32) DEFAULT '';
-/* TODO: why 0-31? Which is default? */
+
CREATE DOMAIN dm_pay_day AS SMALLINT NOT NULL
CHECK ( VALUE BETWEEN 0 AND 31 );
CREATE DOMAIN dm_period AS INTEGER NOT NULL;
CREATE DOMAIN dm_counter AS SMALLINT NOT NULL;
-/* Is it needded? */
+
CREATE DOMAIN dm_message_ver AS INTEGER NOT NULL;
CREATE DOMAIN dm_message_type AS INTEGER NOT NULL;
-/*----------------*/
+
CREATE DOMAIN dm_message AS VARCHAR(256) NOT NULL;
CREATE DOMAIN dm_user_data AS VARCHAR(256) NOT NULL;
CREATE DOMAIN dm_session_event_type AS CHAR(1) NOT NULL
(
pk_user_data dm_id PRIMARY KEY,
fk_user dm_id,
- num dm_num, /* data_id dm_id renamed */
+ num dm_num,
data dm_user_data,
FOREIGN KEY (fk_user) REFERENCES tb_users (pk_user)
END !!
SET TERM ; !!
-/*set term !! ;
-create trigger tr_tariff_bi for tb_tariffs active
-before insert position 0
-as
-begin
- if (new.pk_tariff is null)
- then new.pk_tariff = gen_id(gn_pk_tariff, 1);
-end !!
-set term ; !!*/
-
set term !! ;
create trigger tr_tariff_param_bi for tb_tariffs_params active
before insert position 0
end !!
set term ; !!
-/*set term !! ;
-create trigger tr_user_bi for tb_users active
-before insert position 0
-as
-begin
- if (new.pk_user is null)
- then new.pk_user = gen_id(gn_pk_user, 1);
-end !!
-set term ; !!*/
-
set term !! ;
create trigger tr_detail_stat_bi for tb_detail_stats active
before insert position 0
end !!
set term ; !!
-/*set term !! ;
-create trigger tr_message_bi for tb_messages active
-before insert position 0
-as
-begin
- if (new.pk_message is null)
- then new.pk_message = gen_id(gn_pk_message, 1);
-end !!
-set term ; !!*/
-
-/*set term !! ;
-create trigger tr_stat_bi for tb_stats active
-before insert position 0
-as
-begin
- if (new.pk_stat is null)
- then new.pk_stat = gen_id(gn_pk_stat, 1);
-end !!
-set term ; !!*/
-
set term !! ;
create trigger tr_stat_traffic_bi for tb_stats_traffic active
before insert position 0
end !!
set term ; !!
-/*set term !! ;
-create trigger tr_session_log_bi for tb_sessions_log active
-before insert position 0
-as
-begin
- if (new.pk_session_log is null)
- then new.pk_session_log = gen_id(gn_pk_session_log, 1);
-end !!
-set term ; !!*/
-
set term !! ;
create trigger tr_session_data_bi for tb_sessions_data active
before insert position 0
insert into tb_admins values(0, 'admin', 'geahonjehjfofnhammefahbbbfbmpkmkmmefahbbbfbmpkmkmmefahbbbfbmpkmk', 1, 1, 1, 1, 1, 1, 1, 1, 1);
/* EOF */
-
#include "stg/plugin.h"
#include "stg/logger.h"
#include "stg/scriptexecuter.h"
-#include "stg/conffiles.h"
#include "stg/version.h"
-#include "stg/pinger.h"
#include "stg_timer.h"
#include "settings_impl.h"
#include "users_impl.h"
#include "admins_impl.h"
#include "tariffs_impl.h"
+#include "services_impl.h"
+#include "corps_impl.h"
#include "traffcounter_impl.h"
#include "plugin_runner.h"
#include "store_loader.h"
#include "eventloop.h"
using namespace std;
-uint32_t eip;
#ifdef DEBUG
#define MAIN_DEBUG (1)
#define START_FILE "/._ST_ART_ED_"
-static bool needRulesReloading = false;
-static bool childExited = false;
-//static pid_t executerPid;
set<pid_t> executersPid;
-static pid_t stgChildPid;
-
//-----------------------------------------------------------------------------
bool StartModCmp(const PLUGIN_RUNNER & lhs, const PLUGIN_RUNNER & rhs)
return lhs.GetStopPosition() > rhs.GetStopPosition();
}
//-----------------------------------------------------------------------------
-class STG_STOPPER
-{
-public:
- STG_STOPPER() { nonstop = true; }
- bool GetStatus() const { return nonstop; };
- #ifdef NO_DAEMON
- void Stop(const char * __file__, int __line__)
- #else
- void Stop(const char *, int)
- #endif
- {
- #ifdef NO_DAEMON
- printfd(__FILE__, "Stg stopped at %s:%d\n", __file__, __line__);
- #endif
- nonstop = false;
- }
-private:
- bool nonstop;
-};
-//-----------------------------------------------------------------------------
-STG_STOPPER nonstop;
-//-----------------------------------------------------------------------------
static void StartTimer()
{
STG_LOGGER & WriteServLog = GetStgLogger();
}
}
//-----------------------------------------------------------------------------
-void CatchUSR1(int)
-{
-
-}
-//-----------------------------------------------------------------------------
-void CatchTERM(int sig)
-{
-/*
- *Function Name:CatchINT
- *Parameters: sig_num - ÎÏÍÅÒ ÓÉÇÎÁÌÁ
- *Description: ïÂÒÁÂÏÔÞÉË ÓÉÇÎÁÌÁ INT
- *Returns: îÉÞÅÇÏ
- */
-STG_LOGGER & WriteServLog = GetStgLogger();
-WriteServLog("Shutting down... %d", sig);
-
-//nonstop = false;
-nonstop.Stop(__FILE__, __LINE__);
-
-struct sigaction newsa, oldsa;
-sigset_t sigmask;
-
-sigemptyset(&sigmask);
-sigaddset(&sigmask, SIGTERM);
-newsa.sa_handler = SIG_IGN;
-newsa.sa_mask = sigmask;
-newsa.sa_flags = 0;
-sigaction(SIGTERM, &newsa, &oldsa);
-
-sigemptyset(&sigmask);
-sigaddset(&sigmask, SIGINT);
-newsa.sa_handler = SIG_IGN;
-newsa.sa_mask = sigmask;
-newsa.sa_flags = 0;
-sigaction(SIGINT, &newsa, &oldsa);
-}
-//-----------------------------------------------------------------------------
-void CatchPIPE(int)
-{
-STG_LOGGER & WriteServLog = GetStgLogger();
-WriteServLog("Broken pipe!");
-}
-//-----------------------------------------------------------------------------
-void CatchHUP(int)
-{
-needRulesReloading = true;
-}
-//-----------------------------------------------------------------------------
-void CatchCHLD(int)
-{
-int status;
-pid_t childPid;
-childPid = waitpid(-1, &status, WNOHANG);
-
-set<pid_t>::iterator pid;
-pid = executersPid.find(childPid);
-if (pid != executersPid.end())
- {
- executersPid.erase(pid);
- if (executersPid.empty() && nonstop.GetStatus())
- {
- nonstop.Stop(__FILE__, __LINE__);
- }
- }
-if (childPid == stgChildPid)
- {
- childExited = true;
- }
-}
-/*//-----------------------------------------------------------------------------
-void CatchSEGV(int, siginfo_t *, void *)
-{
-char fileName[50];
-sprintf(fileName, "/tmp/stg_segv.%d", getpid());
-FILE * f = fopen(fileName, "wt");
-if (f)
- {
- fprintf(f, "\nSignal info:\n~~~~~~~~~~~~\n");
- fprintf(f, "numb:\t %d (%d)\n", sinfo->si_signo, sig);
- fprintf(f, "errn:\t %d\n", sinfo->si_errno);
- fprintf(f, "code:\t %d ", sinfo->si_code);
-
- switch (sinfo->si_code)
- {
- case SEGV_MAPERR:
- fprintf(f, "(SEGV_MAPERR - address not mapped to object)\n");
- break;
-
- case SEGV_ACCERR:
- fprintf(f, "(SEGV_ACCERR - invalid permissions for mapped object)\n");
- break;
-
- default:
- fprintf(f, "???\n");
- }
-
- fprintf(f, "addr:\t 0x%.8X\n",
- (unsigned int)sinfo->si_addr);
-
- Dl_info dlinfo;
- //asm("movl %eip, eip");
- if (dladdr((void*)CatchCHLD, &dlinfo))
- {
- fprintf(f, "SEGV point: %s %s\n", dlinfo.dli_fname, dlinfo.dli_sname);
- }
- else
- {
- fprintf(f, "Cannot find SEGV point\n");
- }
-
- fclose(f);
- }
-
-struct sigaction segv_action, segv_action_old;
-
-segv_action.sa_handler = SIG_DFL;
-segv_action.sa_sigaction = NULL;
-segv_action.sa_flags = SA_SIGINFO;
-segv_action.sa_restorer = NULL;
-
-sigaction(SIGSEGV, &segv_action, &segv_action_old);
-}*/
-//-----------------------------------------------------------------------------
-static void SetSignalHandlers()
-{
-struct sigaction newsa, oldsa;
-sigset_t sigmask;
-///////
-sigemptyset(&sigmask);
-sigaddset(&sigmask, SIGTERM);
-newsa.sa_handler = CatchTERM;
-newsa.sa_mask = sigmask;
-newsa.sa_flags = 0;
-sigaction(SIGTERM, &newsa, &oldsa);
-///////
-sigemptyset(&sigmask);
-sigaddset(&sigmask, SIGUSR1);
-newsa.sa_handler = CatchUSR1;
-newsa.sa_mask = sigmask;
-newsa.sa_flags = 0;
-sigaction(SIGUSR1, &newsa, &oldsa);
-///////
-sigemptyset(&sigmask);
-sigaddset(&sigmask, SIGINT);
-newsa.sa_handler = CatchTERM;
-newsa.sa_mask = sigmask;
-newsa.sa_flags = 0;
-sigaction(SIGINT, &newsa, &oldsa);
-//////
-sigemptyset(&sigmask);
-sigaddset(&sigmask, SIGPIPE);
-newsa.sa_handler = CatchPIPE;
-newsa.sa_mask = sigmask;
-newsa.sa_flags = 0;
-sigaction(SIGPIPE, &newsa, &oldsa);
-//////
-sigemptyset(&sigmask);
-sigaddset(&sigmask, SIGHUP);
-newsa.sa_handler = CatchHUP;
-newsa.sa_mask = sigmask;
-newsa.sa_flags = 0;
-sigaction(SIGHUP, &newsa, &oldsa);
-//////
-sigemptyset(&sigmask);
-sigaddset(&sigmask, SIGCHLD);
-newsa.sa_handler = CatchCHLD;
-newsa.sa_mask = sigmask;
-newsa.sa_flags = 0;
-sigaction(SIGCHLD, &newsa, &oldsa);
-
-/*newsa.sa_handler = NULL;
-newsa.sa_sigaction = CatchSEGV;
-newsa.sa_flags = SA_SIGINFO;
-newsa.sa_restorer = NULL;
-sigaction(SIGSEGV, &newsa, &oldsa);*/
-
-return;
-}
-//-----------------------------------------------------------------------------
+#ifdef LINUX
int StartScriptExecuter(char * procName, int msgKey, int * msgID, SETTINGS_IMPL * settings)
+#else
+int StartScriptExecuter(char *, int msgKey, int * msgID, SETTINGS_IMPL * settings)
+#endif
{
STG_LOGGER & WriteServLog = GetStgLogger();
case 0:
delete settings;
- Executer(msgKey, *msgID, executerPid, procName);
+#ifdef LINUX
+ Executer(*msgID, executerPid, procName);
+#else
+ Executer(*msgID, executerPid);
+#endif
return 1;
default:
if (executersPid.empty()) {
- Executer(msgKey, *msgID, executerPid, NULL);
+#ifdef LINUX
+ Executer(*msgID, executerPid, NULL);
+#else
+ Executer(*msgID, executerPid);
+#endif
}
executersPid.insert(executerPid);
}
#endif
{
#ifndef NO_DAEMON
-stgChildPid = fork();
+pid_t childPid = fork();
string startFile = confDir + START_FILE;
unlink(startFile.c_str());
-switch (stgChildPid)
+switch (childPid)
{
case -1:
return -1;
exit(0);
}
- if (childExited)
- {
- unlink(startFile.c_str());
- exit(1);
- }
nanosleep(&ts, NULL);
}
unlink(startFile.c_str());
//-----------------------------------------------------------------------------
int main(int argc, char * argv[])
{
-
-/*
- Initialization order:
- - Logger
- - Stg timer
- - Settings
- - Plugins
- - Plugins settings
- - Read Admins
- - Read Tariffs
- - Read Users
- - Start Users
- - Start Traffcounter
- - Start Plugins
- - Start pinger
- - Set signal nandlers
- - Fork and exit
- * */
-
SETTINGS_IMPL * settings = NULL;
STORE * dataStore = NULL;
TARIFFS_IMPL * tariffs = NULL;
ADMINS_IMPL * admins = NULL;
USERS_IMPL * users = NULL;
TRAFFCOUNTER_IMPL * traffCnt = NULL;
+SERVICES_IMPL * services = NULL;
+CORPORATIONS_IMPL * corps = NULL;
int msgID = -11;
{
PIDFile pidFile(settings->GetPIDFileName());
+sigset_t signalSet;
+sigfillset(&signalSet);
+pthread_sigmask(SIG_BLOCK, &signalSet, NULL);
+
StartTimer();
WaitTimer();
if (!IsStgTimerRunning())
admins = new ADMINS_IMPL(dataStore);
users = new USERS_IMPL(settings, dataStore, tariffs, admins->GetSysAdmin());
traffCnt = new TRAFFCOUNTER_IMPL(users, settings->GetRulesFileName());
+services = new SERVICES_IMPL(dataStore);
+corps = new CORPORATIONS_IMPL(dataStore);
traffCnt->SetMonitorDir(settings->GetMonitorDir());
modSettings = settings->GetModulesSettings();
admins,
tariffs,
users,
+ services,
+ corps,
traffCnt,
dataStore,
settings)
while (modIter != modules.end())
{
- //Loading modules
if (modIter->Load())
{
WriteServLog("Error: %s",
++modIter;
}
-//Start section
if (users->Start())
{
goto exitLblNotStarted;
{
WriteServLog("Error: %s",
modIter->GetStrError().c_str());
- //printfd(__FILE__, "Error: %s\n", capRunner.GetStrError().c_str());
goto exitLbl;
}
WriteServLog("Module: '%s'. Start successfull.", modIter->GetPlugin()->GetVersion().c_str());
++modIter;
}
-SetSignalHandlers();
srandom(stgTime);
-/*
- * Note that an implementation in which nice returns the new nice value
- * can legitimately return -1. To reliably detect an error, set
- * errno to 0 before the call, and check its value when nice returns -1.
- *
- *
- * (c) man 2 nice
- */
-/*errno = 0;
-if (nice(-19) && errno) {
- printfd(__FILE__, "nice failed: '%s'\n", strerror(errno));
- WriteServLog("nice failed: '%s'", strerror(errno));
-}*/
-
WriteServLog("Stg started successfully.");
WriteServLog("+++++++++++++++++++++++++++++++++++++++++++++");
creat(startFile.c_str(), S_IRUSR);
#endif
-while (nonstop.GetStatus())
+while (true)
{
- if (needRulesReloading)
+ sigfillset(&signalSet);
+ int sig = 0;
+ sigwait(&signalSet, &sig);
+ bool stop = false;
+ int status;
+ pid_t childPid;
+ set<pid_t>::iterator it;
+ switch (sig)
{
- needRulesReloading = false;
- traffCnt->Reload();
+ case SIGHUP:
+ traffCnt->Reload();
+ modIter = modules.begin();
+ for (; modIter != modules.end(); ++modIter)
+ {
+ if (modIter->Reload())
+ {
+ WriteServLog("Error reloading %s ('%s')", modIter->GetPlugin()->GetVersion().c_str(),
+ modIter->GetStrError().c_str());
+ printfd(__FILE__, "Error reloading %s ('%s')\n", modIter->GetPlugin()->GetVersion().c_str(),
+ modIter->GetStrError().c_str());
+ }
+ }
+ break;
+ case SIGTERM:
+ stop = true;
+ break;
+ case SIGINT:
+ stop = true;
+ break;
+ case SIGPIPE:
+ WriteServLog("Broken pipe!");
+ break;
+ case SIGCHLD:
+ childPid = waitpid(-1, &status, WNOHANG);
- modIter = modules.begin();
- for (; modIter != modules.end(); ++modIter)
- {
- if (modIter->Reload())
+ it = executersPid.find(childPid);
+ if (it != executersPid.end())
{
- WriteServLog("Error reloading %s ('%s')", modIter->GetPlugin()->GetVersion().c_str(),
- modIter->GetStrError().c_str());
- printfd(__FILE__, "Error reloading %s ('%s')\n", modIter->GetPlugin()->GetVersion().c_str(),
- modIter->GetStrError().c_str());
+ executersPid.erase(it);
+ if (executersPid.empty())
+ stop = true;
}
- }
+ break;
+ default:
+ WriteServLog("Ignore signel %d", sig);
+ break;
}
- stgUsleep(100000);
+ if (stop)
+ break;
}
exitLbl:
modIter->GetPlugin()->GetVersion().c_str(),
modIter->GetStrError().c_str());
printfd(__FILE__, "Failed to stop module '%s'\n", name.c_str());
- //printfd(__FILE__, "Error: %s\n", capRunner.GetStrError().c_str());
- //goto exitLbl;
}
- WriteServLog("Module: \'%s\'. Stop successfull.", modIter->GetPlugin()->GetVersion().c_str());
+ else
+ {
+ WriteServLog("Module: \'%s\'. Stop successfull.", modIter->GetPlugin()->GetVersion().c_str());
+ }
++modIter;
}
while (modIter != modules.end())
{
std::string name = modIter->GetFileName();
- printfd(__FILE__, "Unloading module '%s'\n", name.c_str());
- if (modIter->Unload())
+ if (modIter->IsRunning())
{
- WriteServLog("Module \'%s\': Error: %s",
- name.c_str(),
- modIter->GetStrError().c_str());
- printfd(__FILE__, "Failed to unload module '%s'\n", name.c_str());
+ printfd(__FILE__, "Passing module '%s' `cause it's still running\n", name.c_str());
+ }
+ else
+ {
+ printfd(__FILE__, "Unloading module '%s'\n", name.c_str());
+ if (modIter->Unload())
+ {
+ WriteServLog("Module \'%s\': Error: %s",
+ name.c_str(),
+ modIter->GetStrError().c_str());
+ printfd(__FILE__, "Failed to unload module '%s'\n", name.c_str());
+ }
}
++modIter;
}
StopStgTimer();
WriteServLog("StgTimer: Stop successfull.");
+delete corps;
+delete services;
delete traffCnt;
delete users;
delete admins;
#include "admins_impl.h"
#include "tariffs_impl.h"
#include "users_impl.h"
+#include "services_impl.h"
+#include "corps_impl.h"
//-----------------------------------------------------------------------------
PLUGIN_RUNNER::PLUGIN_RUNNER(const std::string & pFileName,
ADMINS_IMPL * a,
TARIFFS_IMPL * t,
USERS_IMPL * u,
+ SERVICES_IMPL * svc,
+ CORPORATIONS_IMPL * crp,
TRAFFCOUNTER * tc,
STORE * st,
const SETTINGS_IMPL * s)
admins(a),
tariffs(t),
users(u),
+ services(svc),
+ corps(crp),
store(st),
traffCnt(tc),
stgSettings(s),
admins(rvalue.admins),
tariffs(rvalue.tariffs),
users(rvalue.users),
+ services(rvalue.services),
+ corps(rvalue.corps),
store(rvalue.store),
traffCnt(rvalue.traffCnt),
stgSettings(rvalue.stgSettings),
admins = rvalue.admins;
tariffs = rvalue.tariffs;
users = rvalue.users;
+services = rvalue.services;
+corps = rvalue.corps;
store = rvalue.store;
traffCnt = rvalue.traffCnt;
stgSettings = rvalue.stgSettings;
plugin->SetTariffs(tariffs);
plugin->SetAdmins(admins);
plugin->SetUsers(users);
+plugin->SetServices(services);
+plugin->SetCorporations(corps);
plugin->SetTraffcounter(traffCnt);
plugin->SetStore(store);
plugin->SetStgSettings(stgSettings);
return -1;
}
-plugin->Stop();
-
-return 0;
+return plugin->Stop();
}
//-----------------------------------------------------------------------------
int PLUGIN_RUNNER::Reload()
class ADMINS_IMPL;
class TARIFFS_IMPL;
class USERS_IMPL;
+class SERVICES_IMPL;
+class CORPORATIONS_IMPL;
class TRAFFCOUNTER;
class STORE;
ADMINS_IMPL * admins,
TARIFFS_IMPL * tariffs,
USERS_IMPL * users,
+ SERVICES_IMPL * services,
+ CORPORATIONS_IMPL * corporations,
TRAFFCOUNTER * tc,
STORE * store,
const SETTINGS_IMPL * s);
ADMINS_IMPL * admins;
TARIFFS_IMPL * tariffs;
USERS_IMPL * users;
+ SERVICES_IMPL * services;
+ CORPORATIONS_IMPL * corps;
STORE * store;
TRAFFCOUNTER * traffCnt;
const SETTINGS_IMPL * stgSettings;
LN = ln
-CXXFLAGS += -fPIC
-LDFLAGS += -shared -L$(DIR_LIB) -Wl,-rpath,$(PREFIX)/usr/lib/stg
+STGLIBS_INCS = $(addprefix -I ../../../../../stglibs/,$(addsuffix .lib/include,$(STGLIBS)))
+STGLIBS_LIBS = $(addprefix -L ../../../../../stglibs/,$(addsuffix .lib,$(STGLIBS)))
-vpath %.so $(DIR_LIB)
+LIBS += $(addprefix -lstg,$(STGLIBS))
+
+CXXFLAGS += -fPIC $(STGLIBS_INCS)
+CFLAGS += -fPIC $(STGLIBS_INCS)
+LDFLAGS += -shared -Wl,-rpath,$(PREFIX)/usr/lib/stg $(STGLIBS_LIBS)
all: $(PROG)
-$(PROG): $(OBJS) $(STGLIBS)
+$(PROG): $(OBJS)
$(CXX) $^ $(LDFLAGS) $(LIBS) -o $(PROG)
$(LN) -fs "`pwd`/$(PROG)" $(DIR_MOD)/$(PROG)
deps: $(SRCS) ../../../../../Makefile.conf
@>deps ;\
for file in $(SRCS); do\
- echo "`$(CC) $(CXXFLAGS) $(DEFS) $(SEARCH_DIRS) -MM $$file` Makefile ../../../../../Makefile.conf" >> deps ;\
- echo -e '\t$$(CC) -c $$< $(CXXFLAGS) $(SEARCH_DIRS) $(DEFS)' >> deps ;\
+ echo "$$file" | grep ".c$$" > /dev/null;\
+ if [ $$? -eq 0 ];\
+ then\
+ echo "`$(CC) $(CFLAGS) $(DEFS) $(SEARCH_DIRS) -MM $$file` Makefile ../../../../../Makefile.conf" >> deps ;\
+ printf '%b\n' '\t$$(CC) -c $$< $(CFLAGS) $(SEARCH_DIRS) $(DEFS)' >> deps ;\
+ else\
+ echo "`$(CXX) $(CXXFLAGS) $(DEFS) $(SEARCH_DIRS) -MM $$file` Makefile ../../../../../Makefile.conf" >> deps ;\
+ printf '%b\n' '\t$$(CXX) -c $$< $(CXXFLAGS) $(SEARCH_DIRS) $(DEFS)' >> deps ;\
+ fi;\
done
SRCS = ./ao.cpp
-STGLIBS = -lstgcommon
+STGLIBS = common \
+ logger \
+ locker \
+ scriptexecuter
include ../../Makefile.in
#include <unistd.h>
#include <csignal>
+#include <cassert>
#include <algorithm> // for_each
#include <functional> // mem_fun_ref
#include "stg/users.h"
#include "stg/user_property.h"
#include "stg/common.h"
+#include "stg/plugin_creator.h"
#include "ao.h"
-class AO_CREATOR
-{
-private:
- AUTH_AO * ao;
-
-public:
- AO_CREATOR()
- : ao(new AUTH_AO())
- {
- };
- ~AO_CREATOR()
- {
- delete ao;
- };
-
- AUTH_AO * GetPlugin()
- {
- return ao;
- };
-};
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
-AO_CREATOR aoc;
+PLUGIN_CREATOR<AUTH_AO> aoc;
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+PLUGIN * GetPlugin()
+{
+return aoc.GetPlugin();
+}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
-PLUGIN * GetPlugin()
-{
-return aoc.GetPlugin();
-}
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
const string AUTH_AO::GetVersion() const
{
return "Always Online authorizator v.1.0";
}
//-----------------------------------------------------------------------------
AUTH_AO::AUTH_AO()
- : users(NULL),
+ : errorStr(),
+ users(NULL),
+ usersList(),
isRunning(false),
+ settings(),
+ BeforeChgAONotifierList(),
+ AfterChgAONotifierList(),
+ BeforeChgIPNotifierList(),
+ AfterChgIPNotifierList(),
onAddUserNotifier(*this),
onDelUserNotifier(*this)
{
users_iter = usersList.begin();
while (users_iter != usersList.end())
{
- Unauthorize(*users_iter);
+ if ((*users_iter)->IsAuthorizedBy(this))
+ users->Unauthorize((*users_iter)->GetLogin(), this);
UnSetUserNotifiers(*users_iter);
++users_iter;
}
{
USER_PTR u;
int h = users->OpenSearch();
-if (!h)
- {
- printfd(__FILE__, "users->OpenSearch() error\n");
- return;
- }
+assert(h && "USERS::OpenSearch is always correct");
while (!users->SearchNext(h, &u))
{
users->CloseSearch(h);
}
//-----------------------------------------------------------------------------
-void AUTH_AO::Unauthorize(USER_PTR u) const
-{
-u->Unauthorize(this);
-}
-//-----------------------------------------------------------------------------
-void AUTH_AO::UpdateUserAuthorization(USER_PTR u) const
+void AUTH_AO::UpdateUserAuthorization(CONST_USER_PTR u) const
{
if (u->GetProperty().alwaysOnline)
{
USER_IPS ips = u->GetProperty().ips;
if (ips.OnlyOneIP())
{
- if (u->Authorize(ips[0].ip, 0xFFffFFff, this) == 0)
- {
- }
+ users->Authorize(u->GetLogin(), ips[0].ip, 0xFFffFFff, this);
}
}
}
//-----------------------------------------------------------------------------
void AUTH_AO::DelUser(USER_PTR u)
{
-Unauthorize(u);
+users->Unauthorize(u->GetLogin(), this);
UnSetUserNotifiers(u);
usersList.remove(u);
}
void CHG_BEFORE_NOTIFIER<varParamType>::Notify(const varParamType &, const varParamType &)
{
//EVENT_LOOP_SINGLETON::GetInstance().Enqueue(auth, &AUTH_AO::Unauthorize, user);
-auth.Unauthorize(user);
+if (user->IsAuthorizedBy(&auth))
+ auth.users->Unauthorize(user->GetLogin(), &auth);
}
//-----------------------------------------------------------------------------
template <typename varParamType>
class AUTH_AO;
class USERS;
//-----------------------------------------------------------------------------
-template <typename varParamType>
-class CHG_BEFORE_NOTIFIER : public PROPERTY_NOTIFIER_BASE<varParamType> {
+template <typename T>
+class CHG_BEFORE_NOTIFIER : public PROPERTY_NOTIFIER_BASE<T> {
public:
- CHG_BEFORE_NOTIFIER(AUTH_AO & a, USER_PTR u) : user(u), auth(a) {}
- void Notify(const varParamType & oldValue, const varParamType & newValue);
+ CHG_BEFORE_NOTIFIER(AUTH_AO & a, USER_PTR u)
+ : PROPERTY_NOTIFIER_BASE<T>(), user(u), auth(a) {}
+ CHG_BEFORE_NOTIFIER(const CHG_BEFORE_NOTIFIER<T> & rvalue)
+ : PROPERTY_NOTIFIER_BASE<T>(),
+ user(rvalue.user), auth(rvalue.auth) {}
+ void Notify(const T & oldValue, const T & newValue);
USER_PTR GetUser() const { return user; }
private:
+ CHG_BEFORE_NOTIFIER<T> & operator=(const CHG_BEFORE_NOTIFIER<T> & rvalue);
+
USER_PTR user;
const AUTH_AO & auth;
};
//-----------------------------------------------------------------------------
-template <typename varParamType>
-class CHG_AFTER_NOTIFIER : public PROPERTY_NOTIFIER_BASE<varParamType> {
+template <typename T>
+class CHG_AFTER_NOTIFIER : public PROPERTY_NOTIFIER_BASE<T> {
public:
- CHG_AFTER_NOTIFIER(AUTH_AO & a, USER_PTR u) : user(u), auth(a) {}
- void Notify(const varParamType & oldValue, const varParamType & newValue);
+ CHG_AFTER_NOTIFIER(AUTH_AO & a, USER_PTR u)
+ : PROPERTY_NOTIFIER_BASE<T>(), user(u), auth(a) {}
+ CHG_AFTER_NOTIFIER(const CHG_AFTER_NOTIFIER<T> & rvalue)
+ : PROPERTY_NOTIFIER_BASE<T>(),
+ user(rvalue.user), auth(rvalue.auth) {}
+ void Notify(const T & oldValue, const T & newValue);
USER_PTR GetUser() const { return user; }
private:
+ CHG_AFTER_NOTIFIER<T> & operator=(const CHG_AFTER_NOTIFIER<T> & rvalue);
+
USER_PTR user;
const AUTH_AO & auth;
};
virtual ~AUTH_AO(){};
void SetUsers(USERS * u) { users = u; }
- void SetTariffs(TARIFFS *) {}
- void SetAdmins(ADMINS *) {}
- void SetTraffcounter(TRAFFCOUNTER *) {}
- void SetStore(STORE *) {}
- void SetStgSettings(const SETTINGS *) {}
int Start();
int Stop();
void AddUser(USER_PTR u);
void DelUser(USER_PTR u);
- void UpdateUserAuthorization(USER_PTR u) const;
- void Unauthorize(USER_PTR u) const;
-
int SendMessage(const STG_MSG & msg, uint32_t ip) const;
private:
+ AUTH_AO(const AUTH_AO & rvalue);
+ AUTH_AO & operator=(const AUTH_AO & rvalue);
+
void GetUsers();
void SetUserNotifiers(USER_PTR u);
void UnSetUserNotifiers(USER_PTR u);
+ void UpdateUserAuthorization(CONST_USER_PTR u) const;
mutable std::string errorStr;
USERS * users;
public:
ADD_USER_NONIFIER(AUTH_AO & a) : auth(a) {}
virtual ~ADD_USER_NONIFIER() {}
-
- void Notify(const USER_PTR & user)
- {
- auth.AddUser(user);
- }
+ void Notify(const USER_PTR & user) { auth.AddUser(user); }
private:
+ ADD_USER_NONIFIER(const ADD_USER_NONIFIER & rvalue);
+ ADD_USER_NONIFIER & operator=(const ADD_USER_NONIFIER & rvalue);
+
AUTH_AO & auth;
} onAddUserNotifier;
public:
DEL_USER_NONIFIER(AUTH_AO & a) : auth(a) {}
virtual ~DEL_USER_NONIFIER() {}
-
- void Notify(const USER_PTR & user)
- {
- auth.DelUser(user);
- }
+ void Notify(const USER_PTR & user) { auth.DelUser(user); }
private:
+ DEL_USER_NONIFIER(const DEL_USER_NONIFIER & rvalue);
+ DEL_USER_NONIFIER & operator=(const DEL_USER_NONIFIER & rvalue);
+
AUTH_AO & auth;
} onDelUserNotifier;
+ friend class CHG_BEFORE_NOTIFIER<int>;
+ friend class CHG_AFTER_NOTIFIER<int>;
+ friend class CHG_BEFORE_NOTIFIER<USER_IPS>;
+ friend class CHG_AFTER_NOTIFIER<USER_IPS>;
+
};
//-----------------------------------------------------------------------------
SRCS = ./inetaccess.cpp
-STGLIBS = -lstgcommon -lstgcrypto
+STGLIBS = common \
+ crypto \
+ logger \
+ locker \
+ scriptexecuter
include ../../Makefile.in
#include <sys/types.h>
#include <sys/socket.h>
-#include <sys/select.h>
-#include <unistd.h> // usleep, close
+#include <unistd.h> // close
#include <csignal>
#include <cstdlib>
#include "stg/tariff.h"
#include "stg/user_property.h"
#include "stg/settings.h"
+#include "stg/plugin_creator.h"
#include "inetaccess.h"
extern volatile const time_t stgTime;
void Decrypt(BLOWFISH_CTX * ctx, char * dst, const char * src, int len8);
void Encrypt(BLOWFISH_CTX * ctx, char * dst, const char * src, int len8);
-//-----------------------------------------------------------------------------
-class IA_CREATOR
-{
-private:
- AUTH_IA * ia;
-
-public:
- IA_CREATOR()
- : ia(new AUTH_IA())
- {
- };
- ~IA_CREATOR()
- {
- delete ia;
- };
-
- AUTH_IA * GetPlugin()
- {
- return ia;
- };
-};
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
-IA_CREATOR iac;
+PLUGIN_CREATOR<AUTH_IA> iac;
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
: userDelay(0),
userTimeout(0),
port(0),
+ errorStr(),
freeMbShowType(freeMbCash)
{
}
//-----------------------------------------------------------------------------
-int AUTH_IA_SETTINGS::ParseIntInRange(const string & str, int min, int max, int * val)
-{
-if (str2x(str.c_str(), *val))
- {
- errorStr = "Incorrect value \'" + str + "\'.";
- return -1;
- }
-if (*val < min || *val > max)
- {
- errorStr = "Value \'" + str + "\' out of range.";
- return -1;
- }
-return 0;
-}
-//-----------------------------------------------------------------------------
int AUTH_IA_SETTINGS::ParseSettings(const MODULE_SETTINGS & s)
{
int p;
#ifdef IA_PHASE_DEBUG
IA_PHASE::IA_PHASE()
: phase(1),
+ phaseTime(),
flog(NULL)
{
gettimeofday(&phaseTime, NULL);
}
#else
IA_PHASE::IA_PHASE()
- : phase(1)
+ : phase(1),
+ phaseTime()
{
gettimeofday(&phaseTime, NULL);
}
UTIME newPhaseTime;
gettimeofday(&newPhaseTime, NULL);
flog = fopen(log.c_str(), "at");
-/*int64_t tn = newPhaseTime.GetSec()*1000000 + newPhaseTime.GetUSec();
-int64_t to = phaseTime.GetSec()*1000000 + phaseTime.GetUSec();*/
if (flog)
{
string action = newPhase == phase ? "U" : "C";
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
AUTH_IA::AUTH_IA()
- : nonstop(false),
+ : ctxS(),
+ errorStr(),
+ iaSettings(),
+ settings(),
+ nonstop(false),
isRunningRun(false),
isRunningRunTimeouter(false),
users(NULL),
stgSettings(NULL),
+ ip2user(),
+ recvThread(),
+ timeouterThread(),
+ mutex(),
listenSocket(-1),
+ connSynAck6(),
+ connSynAck8(),
+ disconnSynAck6(),
+ disconnSynAck8(),
+ aliveSyn6(),
+ aliveSyn8(),
+ fin6(),
+ fin8(),
+ packetTypes(),
WriteServLog(GetStgLogger()),
enabledDirs(0xFFffFFff),
onDelUserNotifier(*this)
//5 seconds to thread stops itself
for (int i = 0; i < 25 && isRunningRun; i++)
{
- usleep(200000);
- }
-
- //after 5 seconds waiting thread still running. now killing it
- if (isRunningRun)
- {
- //TODO pthread_cancel()
- if (pthread_kill(recvThread, SIGINT))
- {
- errorStr = "Cannot kill thread.";
- printfd(__FILE__, "Cannot kill thread\n");
- return -1;
- }
- for (int i = 0; i < 25 && isRunningRun; ++i)
- usleep(200000);
- if (isRunningRun)
- {
- printfd(__FILE__, "Failed to stop recv thread\n");
- }
- else
- {
- pthread_join(recvThread, NULL);
- }
- printfd(__FILE__, "AUTH_IA killed Run\n");
+ struct timespec ts = {0, 200000000};
+ nanosleep(&ts, NULL);
}
}
//5 seconds to thread stops itself
for (int i = 0; i < 25 && isRunningRunTimeouter; i++)
{
- usleep(200000);
- }
-
- //after 5 seconds waiting thread still running. now killing it
- if (isRunningRunTimeouter)
- {
- //TODO pthread_cancel()
- if (pthread_kill(timeouterThread, SIGINT))
- {
- errorStr = "Cannot kill thread.";
- return -1;
- }
- for (int i = 0; i < 25 && isRunningRunTimeouter; ++i)
- usleep(200000);
- if (isRunningRunTimeouter)
- {
- printfd(__FILE__, "Failed to stop timeouter thread\n");
- }
- else
- {
- pthread_join(timeouterThread, NULL);
- }
- printfd(__FILE__, "AUTH_IA killed Timeouter\n");
+ struct timespec ts = {0, 200000000};
+ nanosleep(&ts, NULL);
}
}
-printfd(__FILE__, "AUTH_IA::Stoped successfully.\n");
+
users->DelNotifierUserDel(&onDelUserNotifier);
+
+if (isRunningRun || isRunningRunTimeouter)
+ return -1;
+
+printfd(__FILE__, "AUTH_IA::Stoped successfully.\n");
return 0;
}
//-----------------------------------------------------------------------------
void * AUTH_IA::Run(void * d)
{
+sigset_t signalSet;
+sigfillset(&signalSet);
+pthread_sigmask(SIG_BLOCK, &signalSet, NULL);
+
AUTH_IA * ia = static_cast<AUTH_IA *>(d);
ia->isRunningRun = true;
//-----------------------------------------------------------------------------
void * AUTH_IA::RunTimeouter(void * d)
{
+sigset_t signalSet;
+sigfillset(&signalSet);
+pthread_sigmask(SIG_BLOCK, &signalSet, NULL);
+
AUTH_IA * ia = static_cast<AUTH_IA *>(d);
ia->isRunningRunTimeouter = true;
string monFile = ia->stgSettings->GetMonitorDir() + "/inetaccess_t";
while (ia->nonstop)
{
- usleep(20000);
+ struct timespec ts = {0, 20000000};
+ nanosleep(&ts, NULL);
ia->Timeouter();
- // TODO cahange counter to timer and MONITOR_TIME_DELAY_SEC
- if (++a % (50*60) == 0 && ia->stgSettings->GetMonitoring())
+ // TODO change counter to timer and MONITOR_TIME_DELAY_SEC
+ if (++a % (50 * 60) == 0 && ia->stgSettings->GetMonitoring())
{
TouchFile(monFile.c_str());
}
return -1;
}
-/*int buffLen;
-if (getsockopt(listenSocket, SOL_SOCKET, SO_SNDBUF, &buffLen, sizeof(buffLen)) < 0)
- {
-
- errorStr = "Getsockopt failed. " + string(strerror(errno));
- return -1;
- }*/
-
-//WriteServLog("buffLen = %d", buffLen);
-
return 0;
}
//-----------------------------------------------------------------------------
Decrypt(&ctxS, login, buffer + 8, PASSWD_LEN / 8);
-uint32_t sip = *((uint32_t*)&outerAddr.sin_addr);
+uint32_t sip = outerAddr.sin_addr.s_addr;
uint16_t sport = htons(outerAddr.sin_port);
USER_PTR user;
-if (users->FindByName(login, &user) == 0)
- {
- printfd(__FILE__, "User %s FOUND!\n", user->GetLogin().c_str());
- PacketProcessor(buffer, dataLen, sip, sport, protoVer, &user);
- }
-else
+if (users->FindByName(login, &user))
{
- WriteServLog("User\'s connect failed:: user \'%s\' not found. IP \'%s\'",
+ WriteServLog("User's connect failed: user '%s' not found. IP %s",
login,
inet_ntostring(sip).c_str());
- printfd(__FILE__, "User %s NOT found!\n", login);
- SendError(sip, sport, protoVer, "îÅÐÒÁ×ÉÌØÎÙÊ ÌÏÇÉÎ ÉÌÉ ÐÁÒÏÌØ!");
+ printfd(__FILE__, "User '%s' NOT found!\n", login);
+ SendError(sip, sport, protoVer, "îÅÐÒÁ×ÉÌØÎÙÊ ÌÏÇÉÎ!");
+ return -1;
}
-return 0;
+printfd(__FILE__, "User '%s' FOUND!\n", user->GetLogin().c_str());
+
+if (user->GetProperty().disabled.Get())
+ {
+ SendError(sip, sport, protoVer, "õÞÅÔÎÁÑ ÚÁÐÉÓØ ÚÁÂÌÏËÉÒÏ×ÁÎÁ");
+ return 0;
+ }
+
+if (user->GetProperty().passive.Get())
+ {
+ SendError(sip, sport, protoVer, "õÞÅÔÎÁÑ ÚÁÐÉÓØ ÚÁÍÏÒÏÖÅÎÁ");
+ return 0;
+ }
+if (!user->GetProperty().ips.Get().IsIPInIPS(sip))
+ {
+ printfd(__FILE__, "User %s. IP address is incorrect. IP %s\n",
+ user->GetLogin().c_str(), inet_ntostring(sip).c_str());
+ WriteServLog("User %s. IP address is incorrect. IP %s",
+ user->GetLogin().c_str(), inet_ntostring(sip).c_str());
+ SendError(sip, sport, protoVer, "ðÏÌØÚÏ×ÁÔÅÌØ ÎÅ ÏÐÏÚÎÁÎ! ðÒÏ×ÅÒØÔÅ IP ÁÄÒÅÓ.");
+ return 0;
+ }
+
+return PacketProcessor(buffer, dataLen, sip, sport, protoVer, user);
}
//-----------------------------------------------------------------------------
int AUTH_IA::CheckHeader(const char * buffer, int * protoVer)
{
it->second.phase.SetPhase1();
printfd(__FILE__, "Phase changed from 2 to 1. Reason: timeout\n");
+ ip2user.erase(it++);
+ continue;
}
if (it->second.phase.GetPhase() == 3)
if ((currTime - it->second.phase.GetTime()) > iaSettings.GetUserTimeout())
{
- it->second.user->Unauthorize(this);
+ users->Unauthorize(it->second.user->GetLogin(), this);
ip2user.erase(it++);
continue;
}
return 0;
}
//-----------------------------------------------------------------------------
-int AUTH_IA::PacketProcessor(char * buff, int dataLen, uint32_t sip, uint16_t sport, int protoVer, USER_PTR * user)
+int AUTH_IA::PacketProcessor(char * buff, int dataLen, uint32_t sip, uint16_t sport, int protoVer, USER_PTR user)
{
-STG_LOCKER lock(&mutex, __FILE__, __LINE__);
-// ôÕÔ ÓÏÂÒÁÎÙ ÏÂÒÁÂÏÔÞÉËÉ ÒÁÚÎÙÈ ÐÁËÅÔÏ×
-int pn = -1;
+std::string login(user->GetLogin());
const int offset = LOGIN_LEN + 2 + 6; // LOGIN_LEN + sizeOfMagic + sizeOfVer;
-IA_USER * iaUser = NULL;
-
-CONN_SYN_6 * connSyn6;
-CONN_SYN_7 * connSyn7;
-CONN_SYN_8 * connSyn8;
-
-CONN_ACK_6 * connAck;
-ALIVE_ACK_6 * aliveAck;
-DISCONN_SYN_6 * disconnSyn;
-DISCONN_ACK_6 * disconnAck;
-
-map<uint32_t, IA_USER>::iterator it;
-it = ip2user.find(sip);
+STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+map<uint32_t, IA_USER>::iterator it(ip2user.find(sip));
-if (it == ip2user.end() || (*user)->GetID() != it->second.user->GetID())
+if (it == ip2user.end())
{
- // åÝÅ ÎÅ ÂÙÌÏ ÚÁÐÒÏÓÏ× Ó ÜÔÏÇÏ IP
- printfd(__FILE__, "Add new user\n");
- ip2user[sip].protoVer = protoVer;
- ip2user[sip].user = *user;
- ip2user[sip].port = sport;
- #ifdef IA_PHASE_DEBUG
- ip2user[sip].phase.SetLogFileName(stgSettings->GetLogFileName());
- ip2user[sip].phase.SetUserLogin((*user)->GetLogin());
- #endif
-
-
- it = ip2user.find(sip); //TODO
- if (it == ip2user.end())
+ USER_PTR userPtr;
+ if (!users->FindByIPIdx(sip, &userPtr))
{
- printfd(__FILE__, "+++ ERROR +++\n");
- return -1;
+ if (userPtr->GetID() != user->GetID())
+ {
+ printfd(__FILE__, "IP address already in use by user '%s'. IP %s, login: '%s'\n",
+ userPtr->GetLogin().c_str(),
+ inet_ntostring(sip).c_str(),
+ login.c_str());
+ WriteServLog("IP address already in use by user '%s'. IP %s, login: '%s'",
+ userPtr->GetLogin().c_str(),
+ inet_ntostring(sip).c_str(),
+ login.c_str());
+ SendError(sip, sport, protoVer, "÷ÁÛ IP ÁÄÒÅÓ ÕÖÅ ÉÓÐÏÌØÚÕÅÔÓÑ!");
+ return 0;
+ }
}
- }
-iaUser = &(it->second);
+ printfd(__FILE__, "Add new user '%s' from ip %s\n",
+ login.c_str(), inet_ntostring(sip).c_str());
+ std::pair<std::map<uint32_t, IA_USER>::iterator, bool> res;
+ res = ip2user.insert(std::make_pair(sip, IA_USER(login, user, sport, protoVer)));
+ it = res.first;
+ #ifdef IA_PHASE_DEBUG
+ it->second.phase.SetLogFileName(stgSettings->GetLogFileName());
+ it->second.phase.SetUserLogin(login);
+ #endif
+ }
+else if (user->GetID() != it->second.user->GetID())
+ {
+ printfd(__FILE__, "IP address already in use by user '%s'. IP %s, login: '%s'\n",
+ it->second.user->GetLogin().c_str(),
+ inet_ntostring(sip).c_str(),
+ user->GetLogin().c_str());
+ WriteServLog("IP address already in use by user '%s'. IP %s, login: '%s'",
+ it->second.user->GetLogin().c_str(),
+ inet_ntostring(sip).c_str(),
+ user->GetLogin().c_str());
+ SendError(sip, sport, protoVer, "÷ÁÛ IP ÁÄÒÅÓ ÕÖÅ ÉÓÐÏÌØÚÕÅÔÓÑ!");
+ return 0;
+ }
-if (iaUser->port != sport)
- iaUser->port = sport;
+IA_USER * iaUser = &(it->second);
-if (iaUser->password != (*user)->GetProperty().password.Get())
+if (iaUser->password != user->GetProperty().password.Get())
{
- InitEncrypt(&iaUser->ctx, (*user)->GetProperty().password.Get());
- iaUser->password = (*user)->GetProperty().password.Get();
+ InitEncrypt(&iaUser->ctx, user->GetProperty().password.Get());
+ iaUser->password = user->GetProperty().password.Get();
}
buff += offset;
strncpy(packetName, buff + 4, IA_MAX_TYPE_LEN);
packetName[IA_MAX_TYPE_LEN - 1] = 0;
-map<string, int>::iterator pi;
-pi = packetTypes.find(packetName);
+map<string, int>::iterator pi(packetTypes.find(packetName));
if (pi == packetTypes.end())
{
SendError(sip, sport, protoVer, "îÅÐÒÁ×ÉÌØÎÙÊ ÌÏÇÉÎ ÉÌÉ ÐÁÒÏÌØ!");
printfd(__FILE__, "Login or password is wrong!\n");
- WriteServLog("User's connect failed. IP \'%s\'. Wrong login or password", inet_ntostring(sip).c_str());
- return 0;
- }
-else
- {
- pn = pi->second;
- }
-
-if ((*user)->GetProperty().disabled.Get())
- {
- SendError(sip, sport, protoVer, "õÞÅÔÎÁÑ ÚÁÐÉÓØ ÚÁÂÌÏËÉÒÏ×ÁÎÁ");
- return 0;
- }
-
-if ((*user)->GetProperty().passive.Get())
- {
- SendError(sip, sport, protoVer, "õÞÅÔÎÁÑ ÚÁÐÉÓØ ÚÁÍÏÒÏÖÅÎÁ");
+ WriteServLog("User's connect failed. User: '%s', ip %s. Wrong login or password",
+ login.c_str(),
+ inet_ntostring(sip).c_str());
+ ip2user.erase(it);
return 0;
}
-if ((*user)->GetAuthorized() && (*user)->GetCurrIP() != sip)
+if (user->IsAuthorizedBy(this) && user->GetCurrIP() != sip)
{
- printfd(__FILE__, "Login %s already in use. IP \'%s\'\n", (*user)->GetLogin().c_str(), inet_ntostring(sip).c_str());
- WriteServLog("Login %s already in use. IP \'%s\'", (*user)->GetLogin().c_str(), inet_ntostring(sip).c_str());
+ printfd(__FILE__, "Login %s already in use from ip %s. IP %s\n",
+ login.c_str(), inet_ntostring(user->GetCurrIP()).c_str(),
+ inet_ntostring(sip).c_str());
+ WriteServLog("Login %s already in use from ip %s. IP %s",
+ login.c_str(),
+ inet_ntostring(user->GetCurrIP()).c_str(),
+ inet_ntostring(sip).c_str());
SendError(sip, sport, protoVer, "÷ÁÛ ÌÏÇÉÎ ÕÖÅ ÉÓÐÏÌØÚÕÅÔÓÑ!");
+ ip2user.erase(it);
return 0;
}
-USER_PTR u;
-if (users->FindByIPIdx(sip, &u) == 0 && u->GetLogin() != (*user)->GetLogin())
- {
- printfd(__FILE__, "IP address already in use. IP \'%s\'", inet_ntostring(sip).c_str());
- WriteServLog("IP address already in use. IP \'%s\'", inet_ntostring(sip).c_str());
- SendError(sip, sport, protoVer, "÷ÁÛ IP ÁÄÒÅÓ ÕÖÅ ÉÓÐÏÌØÚÕÅÔÓÑ!");
- return 0;
- }
-
-// ôÅÐÅÒØ ÍÙ ÄÏÌÖÎÙ ÐÒÏ×ÅÒÉÔØ, ÍÏÖÅÔ ÌÉ ÐÏÌØÚÏ×ÁÔÅÌØ ÐÏÄËÌÀÞÉÔÓÑ Ó ÜÔÏÇÏ ÁÄÒÅÓÁ.
-int ipFound = (*user)->GetProperty().ips.Get().IsIPInIPS(sip);
-if (!ipFound)
- {
- printfd(__FILE__, "User %s. IP address is incorrect. IP \'%s\'\n", (*user)->GetLogin().c_str(), inet_ntostring(sip).c_str());
- WriteServLog("User %s. IP address is incorrect. IP \'%s\'", (*user)->GetLogin().c_str(), inet_ntostring(sip).c_str());
- SendError(sip, sport, protoVer, "ðÏÌØÚÏ×ÁÔÅÌØ ÎÅ ÏÐÏÚÎÁÎ! ðÒÏ×ÅÒØÔÅ IP ÁÄÒÅÓ.");
- return 0;
- }
-
-int ret = -1;
-
-switch (pn)
+switch (pi->second)
{
case CONN_SYN_N:
switch (protoVer)
{
case 6:
- connSyn6 = (CONN_SYN_6*)(buff - offset);
- ret = Process_CONN_SYN_6(connSyn6, &(it->second), sip);
- break;
+ if (Process_CONN_SYN_6((CONN_SYN_6 *)(buff - offset), &(it->second), sip))
+ return -1;
+ return Send_CONN_SYN_ACK_6(iaUser, sip);
case 7:
- connSyn7 = (CONN_SYN_7*)(buff - offset);
- ret = Process_CONN_SYN_7(connSyn7, &(it->second), sip);
- break;
+ if (Process_CONN_SYN_7((CONN_SYN_7 *)(buff - offset), &(it->second), sip))
+ return -1;
+ return Send_CONN_SYN_ACK_7(iaUser, sip);
case 8:
- connSyn8 = (CONN_SYN_8*)(buff - offset);
- ret = Process_CONN_SYN_8(connSyn8, &(it->second), sip);
- break;
- }
-
- if (ret != 0)
- {
- return 0;
- }
- switch (protoVer)
- {
- case 6:
- Send_CONN_SYN_ACK_6(iaUser, sip);
- break;
- case 7:
- Send_CONN_SYN_ACK_7(iaUser, sip);
- break;
- case 8:
- Send_CONN_SYN_ACK_8(iaUser, sip);
- break;
+ if (Process_CONN_SYN_8((CONN_SYN_8 *)(buff - offset), &(it->second), sip))
+ return -1;
+ return Send_CONN_SYN_ACK_8(iaUser, sip);
}
break;
case CONN_ACK_N:
- connAck = (CONN_ACK_6*)(buff - offset);
- switch (protoVer)
- {
- case 6:
- ret = Process_CONN_ACK_6(connAck, iaUser, sip);
- break;
- case 7:
- ret = Process_CONN_ACK_7(connAck, iaUser, sip);
- break;
- case 8:
- ret = Process_CONN_ACK_8((CONN_ACK_8*)(buff - offset), iaUser, sip);
- break;
- }
-
- if (ret != 0)
- {
- SendError(sip, sport, protoVer, errorStr);
- return 0;
- }
-
switch (protoVer)
{
case 6:
- Send_ALIVE_SYN_6(iaUser, sip);
- break;
+ if (Process_CONN_ACK_6((CONN_ACK_6 *)(buff - offset), iaUser, sip))
+ return -1;
+ return Send_ALIVE_SYN_6(iaUser, sip);
case 7:
- Send_ALIVE_SYN_7(iaUser, sip);
- break;
+ if (Process_CONN_ACK_7((CONN_ACK_6 *)(buff - offset), iaUser, sip))
+ return -1;
+ return Send_ALIVE_SYN_7(iaUser, sip);
case 8:
- Send_ALIVE_SYN_8(iaUser, sip);
- break;
+ if (Process_CONN_ACK_8((CONN_ACK_8 *)(buff - offset), iaUser, sip))
+ return -1;
+ return Send_ALIVE_SYN_8(iaUser, sip);
}
-
break;
- // ðÒÉÂÙÌ ÏÔ×ÅÔ Ó ÐÏÄÔ×ÅÒÖÄÅÎÉÅÍ ALIVE
case ALIVE_ACK_N:
- aliveAck = (ALIVE_ACK_6*)(buff - offset);
switch (protoVer)
{
case 6:
- ret = Process_ALIVE_ACK_6(aliveAck, iaUser, sip);
- break;
+ return Process_ALIVE_ACK_6((ALIVE_ACK_6 *)(buff - offset), iaUser, sip);
case 7:
- ret = Process_ALIVE_ACK_7(aliveAck, iaUser, sip);
- break;
+ return Process_ALIVE_ACK_7((ALIVE_ACK_6 *)(buff - offset), iaUser, sip);
case 8:
- ret = Process_ALIVE_ACK_8((ALIVE_ACK_8*)(buff - offset), iaUser, sip);
- break;
+ return Process_ALIVE_ACK_8((ALIVE_ACK_8 *)(buff - offset), iaUser, sip);
}
break;
- // úÁÐÒÏÓ ÎÁ ÏÔËÌÀÞÅÎÉÅ
case DISCONN_SYN_N:
-
- disconnSyn = (DISCONN_SYN_6*)(buff - offset);
switch (protoVer)
{
case 6:
- ret = Process_DISCONN_SYN_6(disconnSyn, iaUser, sip);
- break;
+ if (Process_DISCONN_SYN_6((DISCONN_SYN_6 *)(buff - offset), iaUser, sip))
+ return -1;
+ return Send_DISCONN_SYN_ACK_6(iaUser, sip);
case 7:
- ret = Process_DISCONN_SYN_7(disconnSyn, iaUser, sip);
- break;
+ if (Process_DISCONN_SYN_7((DISCONN_SYN_6 *)(buff - offset), iaUser, sip))
+ return -1;
+ return Send_DISCONN_SYN_ACK_7(iaUser, sip);
case 8:
- ret = Process_DISCONN_SYN_8((DISCONN_SYN_8*)(buff - offset), iaUser, sip);
- break;
- }
-
- if (ret != 0)
- return 0;
-
- switch (protoVer)
- {
- case 6:
- Send_DISCONN_SYN_ACK_6(iaUser, sip);
- break;
- case 7:
- Send_DISCONN_SYN_ACK_7(iaUser, sip);
- break;
- case 8:
- Send_DISCONN_SYN_ACK_8(iaUser, sip);
- break;
+ if (Process_DISCONN_SYN_8((DISCONN_SYN_8 *)(buff - offset), iaUser, sip))
+ return -1;
+ return Send_DISCONN_SYN_ACK_8(iaUser, sip);
}
break;
case DISCONN_ACK_N:
- disconnAck = (DISCONN_ACK_6*)(buff - offset);
-
switch (protoVer)
{
case 6:
- ret = Process_DISCONN_ACK_6(disconnAck, iaUser, sip, it);
- break;
+ if (Process_DISCONN_ACK_6((DISCONN_ACK_6 *)(buff - offset), iaUser, sip, it))
+ return -1;
+ return Send_FIN_6(iaUser, sip, it);
case 7:
- ret = Process_DISCONN_ACK_7(disconnAck, iaUser, sip, it);
- break;
+ if (Process_DISCONN_ACK_7((DISCONN_ACK_6 *)(buff - offset), iaUser, sip, it))
+ return -1;
+ return Send_FIN_7(iaUser, sip, it);
case 8:
- ret = Process_DISCONN_ACK_8((DISCONN_ACK_8*)(buff - offset), iaUser, sip, it);
- break;
- }
-
- switch (protoVer)
- {
- case 6:
- Send_FIN_6(iaUser, sip, it);
- break;
- case 7:
- Send_FIN_7(iaUser, sip, it);
- break;
- case 8:
- Send_FIN_8(iaUser, sip, it);
- break;
+ if (Process_DISCONN_ACK_8((DISCONN_ACK_8 *)(buff - offset), iaUser, sip, it))
+ return -1;
+ return Send_FIN_8(iaUser, sip, it);
}
break;
}
-return 0;
+return -1;
}
//-----------------------------------------------------------------------------
void AUTH_IA::DelUser(USER_PTR u)
{
-STG_LOCKER lock(&mutex, __FILE__, __LINE__);
uint32_t ip = u->GetCurrIP();
return;
map<uint32_t, IA_USER>::iterator it;
+
+STG_LOCKER lock(&mutex, __FILE__, __LINE__);
it = ip2user.find(ip);
if (it == ip2user.end())
{
if (it->second.user == u)
{
printfd(__FILE__, "User removed!\n");
- it->second.user->Unauthorize(this);
+ users->Unauthorize(u->GetLogin(), this);
ip2user.erase(it);
}
}
sendAddr.sin_family = AF_INET;
sendAddr.sin_port = htons(port);
-
- sendAddr.sin_addr.s_addr = ip;// IP ÐÏÌØÚÏ×ÁÔÅÌÑ
+ sendAddr.sin_addr.s_addr = ip;
err.len = 1;
strncpy((char*)err.type, "ERR", 16);
sendAddr.sin_family = AF_INET;
sendAddr.sin_port = htons(port);
-
- sendAddr.sin_addr.s_addr = ip;// IP ÐÏÌØÚÏ×ÁÔÅÌÑ
+ sendAddr.sin_addr.s_addr = ip;
err8.len = 256;
strncpy((char*)err8.type, "ERR", 16);
int AUTH_IA::Send(uint32_t ip, uint16_t port, const char * buffer, int len)
{
struct sockaddr_in sendAddr;
-int res;
sendAddr.sin_family = AF_INET;
sendAddr.sin_port = htons(port);
sendAddr.sin_addr.s_addr = ip;
-res = sendto(listenSocket, buffer, len, 0, (struct sockaddr*)&sendAddr, sizeof(sendAddr));
+int res = sendto(listenSocket, buffer, len, 0, (struct sockaddr*)&sendAddr, sizeof(sendAddr));
-static struct timeval tv;
-gettimeofday(&tv, NULL);
+if (res == len)
+ return 0;
-return res;
+return -1;
}
//-----------------------------------------------------------------------------
int AUTH_IA::SendMessage(const STG_MSG & msg, uint32_t ip) const
{
-STG_LOCKER lock(&mutex, __FILE__, __LINE__);
-
printfd(__FILE__, "SendMessage userIP=%s\n", inet_ntostring(ip).c_str());
map<uint32_t, IA_USER>::iterator it;
+
+STG_LOCKER lock(&mutex, __FILE__, __LINE__);
it = ip2user.find(ip);
if (it == ip2user.end())
{
//-----------------------------------------------------------------------------
int AUTH_IA::RealSendMessage6(const STG_MSG & msg, uint32_t ip, IA_USER & user)
{
-printfd(__FILE__, "RealSendMessage 6 user=%s\n", user.user->GetLogin().c_str());
+printfd(__FILE__, "RealSendMessage 6 user=%s\n", user.login.c_str());
-char buffer[256];
INFO_6 info;
-
memset(&info, 0, sizeof(INFO_6));
info.len = 256;
SwapBytes(info.len);
#endif
+char buffer[256];
memcpy(buffer, &info, sizeof(INFO_6));
Encrypt(&user.ctx, buffer, buffer, len / 8);
-Send(ip, iaSettings.GetUserPort(), buffer, len);
-
-return 0;
+return Send(ip, iaSettings.GetUserPort(), buffer, len);
}
//-----------------------------------------------------------------------------
int AUTH_IA::RealSendMessage7(const STG_MSG & msg, uint32_t ip, IA_USER & user)
{
-printfd(__FILE__, "RealSendMessage 7 user=%s\n", user.user->GetLogin().c_str());
+printfd(__FILE__, "RealSendMessage 7 user=%s\n", user.login.c_str());
-char buffer[300];
INFO_7 info;
-
memset(&info, 0, sizeof(INFO_7));
info.len = 264;
strncpy((char*)info.type, "INFO_7", 16);
info.infoType = msg.header.type;
info.showTime = msg.header.showTime;
-
info.sendTime = msg.header.creationTime;
size_t len = info.len;
strncpy((char*)info.text, msg.text.c_str(), MAX_MSG_LEN - 1);
info.text[MAX_MSG_LEN - 1] = 0;
+char buffer[300];
memcpy(buffer, &info, sizeof(INFO_7));
Encrypt(&user.ctx, buffer, buffer, len / 8);
-Send(ip, iaSettings.GetUserPort(), buffer, len);
-
-return 0;
+return Send(ip, iaSettings.GetUserPort(), buffer, len);
}
//-----------------------------------------------------------------------------
int AUTH_IA::RealSendMessage8(const STG_MSG & msg, uint32_t ip, IA_USER & user)
{
-printfd(__FILE__, "RealSendMessage 8 user=%s\n", user.user->GetLogin().c_str());
-
-char buffer[1500];
-memset(buffer, 0, sizeof(buffer));
+printfd(__FILE__, "RealSendMessage 8 user=%s\n", user.login.c_str());
INFO_8 info;
-
memset(&info, 0, sizeof(INFO_8));
info.len = 1056;
SwapBytes(info.sendTime);
#endif
+char buffer[1500];
memcpy(buffer, &info, sizeof(INFO_8));
Encrypt(&user.ctx, buffer, buffer, len / 8);
-Send(ip, user.port, buffer, len);
-
-return 0;
+return Send(ip, user.port, buffer, len);
}
//-----------------------------------------------------------------------------
int AUTH_IA::Process_CONN_SYN_6(CONN_SYN_6 *, IA_USER * iaUser, uint32_t)
SwapBytes(connAck->rnd);
#endif
printfd( __FILE__, "CONN_ACK_6 %s\n", connAck->type);
-// ÕÓÔÁÎÏ×ÉÔØ ÎÏ×ÕÀ ÆÁÚÕ É ×ÒÅÍÑ É ÒÁÚÒÅÛÉÔØ ÉÎÅÔ
+
if ((iaUser->phase.GetPhase() == 2) && (connAck->rnd == iaUser->rnd + 1))
{
iaUser->phase.UpdateTime();
iaUser->lastSendAlive = iaUser->phase.GetTime();
- if (iaUser->user->Authorize(sip, enabledDirs, this) == 0)
+ if (users->Authorize(iaUser->login, sip, enabledDirs, this))
{
iaUser->phase.SetPhase3();
printfd(__FILE__, "Phase changed from 2 to 3. Reason: CONN_ACK_6\n");
{
errorStr = iaUser->user->GetStrError();
iaUser->phase.SetPhase1();
+ ip2user.erase(sip);
printfd(__FILE__, "Phase changed from 2 to 1. Reason: failed to authorize user\n");
return -1;
}
{
iaUser->phase.UpdateTime();
iaUser->lastSendAlive = iaUser->phase.GetTime();
- if (iaUser->user->Authorize(sip, enabledDirs, this) == 0)
+ if (users->Authorize(iaUser->login, sip, enabledDirs, this))
{
iaUser->phase.SetPhase3();
printfd(__FILE__, "Phase changed from 2 to 3. Reason: CONN_ACK_8\n");
{
errorStr = iaUser->user->GetStrError();
iaUser->phase.SetPhase1();
+ ip2user.erase(sip);
printfd(__FILE__, "Phase changed from 2 to 1. Reason: failed to authorize user\n");
return -1;
}
Encrypt(&iaUser->ctx, (char*)&connSynAck8, (char*)&connSynAck8, Min8(sizeof(CONN_SYN_ACK_8))/8);
return Send(sip, iaUser->port, (char*)&connSynAck8, Min8(sizeof(CONN_SYN_ACK_8)));
-//return Send(sip, iaUser->port, (char*)&connSynAck8, 384);
}
//-----------------------------------------------------------------------------
int AUTH_IA::Send_ALIVE_SYN_6(IA_USER * iaUser, uint32_t sip)
#ifdef IA_DEBUG
if (iaUser->aliveSent)
{
- printfd(__FILE__, "========= ALIVE_ACK_6(7) TIMEOUT !!! %s =========\n", iaUser->user->GetLogin().c_str());
+ printfd(__FILE__, "========= ALIVE_ACK_6(7) TIMEOUT !!! %s =========\n", iaUser->login.c_str());
}
iaUser->aliveSent = true;
#endif
Encrypt(&iaUser->ctx, (char*)&fin6, (char*)&fin6, Min8(sizeof(fin6))/8);
-iaUser->user->Unauthorize(this);
+users->Unauthorize(iaUser->login, this);
+
+int res = Send(sip, iaSettings.GetUserPort(), (char*)&fin6, Min8(sizeof(fin6)));
-int ret = Send(sip, iaSettings.GetUserPort(), (char*)&fin6, Min8(sizeof(fin6)));
ip2user.erase(it);
-return ret;
+
+return res;
}
//-----------------------------------------------------------------------------
int AUTH_IA::Send_FIN_7(IA_USER * iaUser, uint32_t sip, map<uint32_t, IA_USER>::iterator it)
Encrypt(&iaUser->ctx, (char*)&fin8, (char*)&fin8, Min8(sizeof(fin8))/8);
-iaUser->user->Unauthorize(this);
-
-int ret = Send(sip, iaUser->port, (char*)&fin8, Min8(sizeof(fin8)));
-ip2user.erase(it);
-return ret;
-}
-//-----------------------------------------------------------------------------
-bool AUTH_IA::WaitPackets(int sd) const
-{
-fd_set rfds;
-FD_ZERO(&rfds);
-FD_SET(sd, &rfds);
-
-struct timeval tv;
-tv.tv_sec = 0;
-tv.tv_usec = 500000;
+users->Unauthorize(iaUser->login, this);
-int res = select(sd + 1, &rfds, NULL, NULL, &tv);
-if (res == -1) // Error
- {
- if (errno != EINTR)
- {
- printfd(__FILE__, "Error on select: '%s'\n", strerror(errno));
- }
- return false;
- }
+int res = Send(sip, iaUser->port, (char*)&fin8, Min8(sizeof(fin8)));
-if (res == 0) // Timeout
- {
- return false;
- }
+ip2user.erase(it);
-return true;
+return res;
}
//-----------------------------------------------------------------------------
inline
void InitEncrypt(BLOWFISH_CTX * ctx, const string & password)
{
-unsigned char keyL[PASSWD_LEN]; // ðÁÒÏÌØ ÄÌÑ ÛÉÆÒÏ×ËÉ
+unsigned char keyL[PASSWD_LEN];
memset(keyL, 0, PASSWD_LEN);
strncpy((char *)keyL, password.c_str(), PASSWD_LEN);
Blowfish_Init(ctx, keyL, PASSWD_LEN);
inline
void Decrypt(BLOWFISH_CTX * ctx, char * dst, const char * src, int len8)
{
-// len8 - ÄÌÉÎÁ × 8-ÍÉ ÂÁÊÔÏ×ÙÈ ÂÌÏËÁÈ
-
for (int i = 0; i < len8; i++)
DecodeString(dst + i * 8, src + i * 8, ctx);
}
inline
void Encrypt(BLOWFISH_CTX * ctx, char * dst, const char * src, int len8)
{
-// len8 - ÄÌÉÎÁ × 8-ÍÉ ÂÁÊÔÏ×ÙÈ ÂÌÏËÁÈ
-
for (int i = 0; i < len8; i++)
EncodeString(dst + i * 8, src + i * 8, ctx);
}
//-----------------------------------------------------------------------------
struct IA_USER {
IA_USER()
- : user(NULL),
+ : login(),
+ user(NULL),
+ phase(),
lastSendAlive(0),
rnd(random()),
port(0),
+ ctx(),
+ messagesToSend(),
protoVer(0),
password("NO PASSWORD")
{
- // +++ Preparing CTX +++
- unsigned char keyL[PASSWD_LEN];
- memset(keyL, 0, PASSWD_LEN);
- strncpy((char *)keyL, password.c_str(), PASSWD_LEN);
- Blowfish_Init(&ctx, keyL, PASSWD_LEN);
- // --- Preparing CTX ---
- #ifdef IA_DEBUG
- aliveSent = false;
- #endif
+ unsigned char keyL[PASSWD_LEN];
+ memset(keyL, 0, PASSWD_LEN);
+ strncpy((char *)keyL, password.c_str(), PASSWD_LEN);
+ Blowfish_Init(&ctx, keyL, PASSWD_LEN);
+
+ #ifdef IA_DEBUG
+ aliveSent = false;
+ #endif
};
IA_USER(const IA_USER & u)
- : user(u.user),
+ : login(u.login),
+ user(u.user),
phase(u.phase),
lastSendAlive(u.lastSendAlive),
rnd(u.rnd),
port(u.port),
+ ctx(),
messagesToSend(u.messagesToSend),
protoVer(u.protoVer),
password(u.password)
{
- #ifdef IA_DEBUG
- aliveSent = u.aliveSent;
- #endif
- memcpy(&ctx, &u.ctx, sizeof(BLOWFISH_CTX));
+ #ifdef IA_DEBUG
+ aliveSent = u.aliveSent;
+ #endif
+ memcpy(&ctx, &u.ctx, sizeof(BLOWFISH_CTX));
};
- USER_PTR user;
+ IA_USER(const std::string & l,
+ CONST_USER_PTR u,
+ uint16_t p,
+ int ver)
+ : login(l),
+ user(u),
+ phase(),
+ lastSendAlive(0),
+ rnd(random()),
+ port(p),
+ ctx(),
+ messagesToSend(),
+ protoVer(ver),
+ password(user->GetProperty().password.Get())
+ {
+ unsigned char keyL[PASSWD_LEN];
+ memset(keyL, 0, PASSWD_LEN);
+ strncpy((char *)keyL, password.c_str(), PASSWD_LEN);
+ Blowfish_Init(&ctx, keyL, PASSWD_LEN);
+
+ #ifdef IA_DEBUG
+ aliveSent = false;
+ #endif
+ }
+
+ std::string login;
+ CONST_USER_PTR user;
IA_PHASE phase;
UTIME lastSendAlive;
uint32_t rnd;
#ifdef IA_DEBUG
bool aliveSent;
#endif
+
+private:
+ IA_USER & operator=(const IA_USER & rvalue);
};
//-----------------------------------------------------------------------------
class AUTH_IA_SETTINGS {
FREEMB GetFreeMbShowType() const { return freeMbShowType; };
private:
- int ParseIntInRange(const std::string & str, int min, int max, int * val);
int userDelay;
int userTimeout;
uint16_t port;
void Notify(const USER_PTR & user);
private:
+ DEL_USER_NOTIFIER(const DEL_USER_NOTIFIER & rvalue);
+ DEL_USER_NOTIFIER & operator=(const DEL_USER_NOTIFIER & rvalue);
+
AUTH_IA & auth;
};
//-----------------------------------------------------------------------------
virtual ~AUTH_IA();
void SetUsers(USERS * u) { users = u; }
- void SetTariffs(TARIFFS *) {}
- void SetAdmins(ADMINS *) {}
- void SetTraffcounter(TRAFFCOUNTER *) {}
- void SetStore(STORE *) {}
void SetStgSettings(const SETTINGS * s) { stgSettings = s; }
void SetSettings(const MODULE_SETTINGS & s) { settings = s; }
int ParseSettings();
int SendMessage(const STG_MSG & msg, uint32_t ip) const;
private:
+ AUTH_IA(const AUTH_IA & rvalue);
+ AUTH_IA & operator=(const AUTH_IA & rvalue);
+
static void * Run(void *);
static void * RunTimeouter(void * d);
int PrepareNet();
void DelUser(USER_PTR u);
int RecvData(char * buffer, int bufferSize);
int CheckHeader(const char * buffer, int * protoVer);
- int PacketProcessor(char * buff, int dataLen, uint32_t sip, uint16_t sport, int protoVer, USER_PTR * user);
+ int PacketProcessor(char * buff, int dataLen, uint32_t sip, uint16_t sport, int protoVer, USER_PTR user);
int Process_CONN_SYN_6(CONN_SYN_6 * connSyn, IA_USER * iaUser, uint32_t sip);
int Process_CONN_SYN_7(CONN_SYN_7 * connSyn, IA_USER * iaUser, uint32_t sip);
int RealSendMessage7(const STG_MSG & msg, uint32_t ip, IA_USER & user);
int RealSendMessage8(const STG_MSG & msg, uint32_t ip, IA_USER & user);
- bool WaitPackets(int sd) const;
-
BLOWFISH_CTX ctxS; //for loginS
mutable std::string errorStr;
DEL_USER_NOTIFIER onDelUserNotifier;
- class UnauthorizeUser : std::unary_function<const std::pair<uint32_t, IA_USER> &, void> {
- public:
- UnauthorizeUser(AUTH_IA * a) : auth(a) {}
- void operator()(const std::pair<uint32_t, IA_USER> & p)
- {
- p.second.user->Unauthorize(auth);
- }
- private:
- AUTH_IA * auth;
- };
-
+ friend class UnauthorizeUser;
+};
+//-----------------------------------------------------------------------------
+class UnauthorizeUser : std::unary_function<const std::pair<uint32_t, IA_USER> &, void> {
+ public:
+ UnauthorizeUser(AUTH_IA * a) : auth(a) {}
+ UnauthorizeUser(const UnauthorizeUser & rvalue) : auth(rvalue.auth) {}
+ void operator()(const std::pair<uint32_t, IA_USER> & p)
+ {
+ auth->users->Unauthorize(p.second.user->GetLogin(), auth);
+ }
+ private:
+ UnauthorizeUser & operator=(const UnauthorizeUser & rvalue);
+
+ AUTH_IA * auth;
};
//-----------------------------------------------------------------------------
inline
LIBS += $(LIB_THREAD)
+STGLIBS = common \
+ logger \
+ locker \
+ scriptexecuter
+
include ../../Makefile.in
#include "stg/user.h"
#include "stg/common.h"
#include "stg/user_property.h"
+#include "stg/plugin_creator.h"
#include "stress.h"
-class STRESS_CREATOR
-{
-private:
- AUTH_STRESS * dc;
-
-public:
- STRESS_CREATOR()
- {
- printfd(__FILE__, "constructor STRESS_CREATOR\n");
- dc = new AUTH_STRESS();
- };
- ~STRESS_CREATOR()
- {
- printfd(__FILE__, "destructor STRESS_CREATOR\n");
- delete dc;
- };
-
- PLUGIN * GetPlugin()
- {
- return dc;
- };
-};
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
-STRESS_CREATOR stressc;
+PLUGIN_CREATOR<AUTH_STRESS> stressc;
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
{
}
//-----------------------------------------------------------------------------
-int AUTH_STRESS_SETTINGS::ParseIntInRange(const string & str, int min, int max, int * val)
-{
-if (str2x(str.c_str(), *val))
- {
- errorStr = "Incorrect value \'" + str + "\'.";
- return -1;
- }
-if (*val < min || *val > max)
- {
- errorStr = "Value \'" + str + "\' out of range.";
- return -1;
- }
-return 0;
-}
-//-----------------------------------------------------------------------------
int AUTH_STRESS_SETTINGS::ParseSettings(const MODULE_SETTINGS & s)
{
PARAM_VALUE pv;
{
if (!isRunning)
break;
- usleep(200000);
+ struct timespec ts = {0, 200000000};
+ nanosleep(&ts, NULL);
}
//after 5 seconds waiting thread still running. now killing it
int ParseSettings(const MODULE_SETTINGS & s);
int GetAverageOnlineTime() const;
private:
- int ParseIntInRange(const std::string & str, int min, int max, int * val);
int averageOnlineTime;
std::string errorStr;
};
virtual ~AUTH_STRESS() {}
void SetUsers(USERS * u);
- void SetTariffs(TARIFFS *) {}
- void SetAdmins(ADMINS *) {}
- void SetTraffcounter(TRAFFCOUNTER *) {}
- void SetStore(STORE *) {}
- void SetStgSettings(const SETTINGS *) {}
int Start();
int Stop();
./tcp.c \
./udp.c
-STGLIBS = -lstgcommon
+STGLIBS = common
LIBS += $(LIB_THREAD)
#include <netinet/in.h>
#include <arpa/inet.h>
-#include "debug_cap.h"
-#include "../../../traffcounter.h"
#include "libpal.h"
+#include "stg/plugin_creator.h"
+#include "stg/traffcounter.h"
+#include "debug_cap.h"
//-----------------------------------------------------------------------------
void WriteStat(uint32_t u, uint32_t d)
fclose(f);
}
//-----------------------------------------------------------------------------
-
-class CAP_DEBUG_CREATOR
-{
-private:
- DEBUG_CAP * dc;
-
-public:
- CAP_DEBUG_CREATOR()
- : dc(new DEBUG_CAP())
- {
- };
- ~CAP_DEBUG_CREATOR()
- {
- delete dc;
- };
-
- DEBUG_CAP * GetCapturer()
- {
- return dc;
- };
-};
-//-----------------------------------------------------------------------------
-RAW_PACKET MakeTCPPacket(const char * src,
- const char * dst,
- uint16_t sport,
- uint16_t dport,
- uint16_t len);
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
-CAP_DEBUG_CREATOR cdc;
+PLUGIN_CREATOR<DEBUG_CAP> cdc;
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
BASE_PLUGIN * GetPlugin()
{
-return cdc.GetCapturer();
+return cdc.GetPlugin();
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+RAW_PACKET MakeTCPPacket(const char * src,
+ const char * dst,
+ uint16_t sport,
+ uint16_t dport,
+ uint16_t len);
const string DEBUG_CAP::GetVersion() const
{
return "Debug_cap v.0.01a";
#include <string>
-#include "os_int.h"
-#include "plugin.h"
-#include "module_settings.h"
+#include "stg/os_int.h"
+#include "stg/plugin.h"
+#include "stg/module_settings.h"
using namespace std;
extern "C" PLUGIN * GetPlugin();
DEBUG_CAP();
virtual ~DEBUG_CAP() {}
- void SetUsers(USERS * u) {}
- void SetTariffs(TARIFFS * t) {}
- void SetAdmins(ADMINS * a) {}
void SetTraffcounter(TRAFFCOUNTER * tc);
- void SetStore(STORE *) {}
- void SetStgSettings(const SETTINGS *) {}
int Start();
int Stop();
int Reload() { return 0; }
int ParseSettings() { return 0; }
- void SetSettings(const MODULE_SETTINGS & s) {}
bool IsRunning();
const string & GetStrError() const;
const string GetVersion() const;
SRCS = ./cap_nf.cpp
LIBS += $(LIB_THREAD)
-STGLIBS = -lstgcommon
+
+STGLIBS = common
include ../../Makefile.in
#include "stg/common.h"
#include "stg/raw_ip_packet.h"
#include "stg/traffcounter.h"
+#include "stg/plugin_creator.h"
#include "cap_nf.h"
-class CAP_NF_CREATOR {
-public:
- CAP_NF_CREATOR()
- : nf(new NF_CAP())
- {
- }
-
- ~CAP_NF_CREATOR()
- {
- delete nf;
- }
-
- NF_CAP * GetCapturer() { return nf; }
-private:
- NF_CAP * nf;
-} cnc;
+PLUGIN_CREATOR<NF_CAP> cnc;
PLUGIN * GetPlugin()
{
-return cnc.GetCapturer();
+return cnc.GetPlugin();
}
NF_CAP::NF_CAP()
: traffCnt(NULL),
- tidTCP(0),
- tidUDP(0),
+ settings(),
+ tidTCP(),
+ tidUDP(),
runningTCP(false),
runningUDP(false),
stoppedTCP(true),
portT(0),
portU(0),
sockTCP(-1),
- sockUDP(-1)
+ sockUDP(-1),
+ errorStr()
{
}
CloseUDP();
for (int i = 0; i < 25 && !stoppedUDP; ++i)
{
- usleep(200000);
+ struct timespec ts = {0, 200000000};
+ nanosleep(&ts, NULL);
}
if (stoppedUDP)
{
CloseTCP();
for (int i = 0; i < 25 && !stoppedTCP; ++i)
{
- usleep(200000);
+ struct timespec ts = {0, 200000000};
+ nanosleep(&ts, NULL);
}
if (stoppedTCP)
{
void * NF_CAP::RunUDP(void * c)
{
+sigset_t signalSet;
+sigfillset(&signalSet);
+pthread_sigmask(SIG_BLOCK, &signalSet, NULL);
+
NF_CAP * cap = static_cast<NF_CAP *>(c);
uint8_t buf[BUF_SIZE];
int res;
cap->stoppedUDP = false;
while (cap->runningUDP)
{
- if (!cap->WaitPackets(cap->sockUDP))
+ if (!WaitPackets(cap->sockUDP))
{
continue;
}
void * NF_CAP::RunTCP(void * c)
{
+sigset_t signalSet;
+sigfillset(&signalSet);
+pthread_sigmask(SIG_BLOCK, &signalSet, NULL);
+
NF_CAP * cap = static_cast<NF_CAP *>(c);
uint8_t buf[BUF_SIZE];
int res;
cap->stoppedTCP = false;
while (cap->runningTCP)
{
- if (!cap->WaitPackets(cap->sockTCP))
+ if (!WaitPackets(cap->sockTCP))
{
continue;
}
continue;
}
- if (!cap->WaitPackets(sd))
+ if (!WaitPackets(sd))
{
close(sd);
continue;
{
NF_DATA * data = reinterpret_cast<NF_DATA *>(buf + 24 + i * 48);
- ip.header.ipHeader.ip_v = 4;
- ip.header.ipHeader.ip_hl = 5;
- ip.header.ipHeader.ip_p = data->proto;
+ ip.rawPacket.header.ipHeader.ip_v = 4;
+ ip.rawPacket.header.ipHeader.ip_hl = 5;
+ ip.rawPacket.header.ipHeader.ip_p = data->proto;
ip.dataLen = ntohl(data->octets);
- ip.header.ipHeader.ip_src.s_addr = data->srcAddr;
- ip.header.ipHeader.ip_dst.s_addr = data->dstAddr;
- ip.header.sPort = data->srcPort;
- ip.header.dPort = data->dstPort;
+ ip.rawPacket.header.ipHeader.ip_src.s_addr = data->srcAddr;
+ ip.rawPacket.header.ipHeader.ip_dst.s_addr = data->dstAddr;
+ ip.rawPacket.header.sPort = data->srcPort;
+ ip.rawPacket.header.dPort = data->dstPort;
traffCnt->Process(ip);
}
}
-
-bool NF_CAP::WaitPackets(int sd) const
-{
-fd_set rfds;
-FD_ZERO(&rfds);
-FD_SET(sd, &rfds);
-
-struct timeval tv;
-tv.tv_sec = 0;
-tv.tv_usec = 500000;
-
-int res = select(sd + 1, &rfds, NULL, NULL, &tv);
-if (res == -1) // Error
- {
- if (errno != EINTR)
- {
- printfd(__FILE__, "Error on select: '%s'\n", strerror(errno));
- }
- return false;
- }
-
-if (res == 0) // Timeout
- {
- return false;
- }
-
-return true;
-}
NF_CAP();
~NF_CAP();
- void SetUsers(USERS *) {}
- void SetTariffs(TARIFFS *) {}
- void SetAdmins(ADMINS *) {}
void SetTraffcounter(TRAFFCOUNTER * tc) { traffCnt = tc; }
- void SetStore(STORE *) {}
- void SetStgSettings(const SETTINGS *) {}
void SetSettings(const MODULE_SETTINGS & s) { settings = s; }
int ParseSettings();
uint16_t GetStopPosition() const { return STOP_POS; }
private:
+ NF_CAP(const NF_CAP & rvalue);
+ NF_CAP & operator=(const NF_CAP & rvalue);
+
TRAFFCOUNTER * traffCnt;
MODULE_SETTINGS settings;
pthread_t tidTCP;
bool OpenUDP();
void CloseTCP() { close(sockTCP); }
void CloseUDP() { close(sockUDP); }
-
- bool WaitPackets(int sd) const;
};
extern "C" PLUGIN * GetPlugin();
SRCS = ./divert_cap.cpp
-STGLIBS = -lstgcommon
-
LIBS += $(LIB_THREAD)
+STGLIBS = common
+
include ../../Makefile.in
#include "stg/common.h"
#include "stg/traffcounter.h"
+#include "stg/plugin_creator.h"
#include "divert_cap.h"
#define BUFF_LEN (16384) /* max mtu -> lo=16436 TODO why?*/
pollfd pollddiv;
DIVERT_DATA cddiv; //capture data
//-----------------------------------------------------------------------------
-class DIVERT_CAP_CREATOR {
-private:
- DIVERT_CAP * divc;
-
-public:
- DIVERT_CAP_CREATOR()
- : divc(new DIVERT_CAP())
- {
- }
- ~DIVERT_CAP_CREATOR()
- {
- delete divc;
- }
-
- DIVERT_CAP * GetCapturer()
- {
- return divc;
- }
-};
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-DIVERT_CAP_CREATOR dcc;
+PLUGIN_CREATOR<DIVERT_CAP> dcc;
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
PLUGIN * GetPlugin()
{
-return dcc.GetCapturer();
+return dcc.GetPlugin();
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
}
//-----------------------------------------------------------------------------
DIVERT_CAP::DIVERT_CAP()
- : port(0),
+ : settings(),
+ port(0),
+ errorStr(),
+ thread(),
nonstop(false),
isRunning(false),
traffCnt(NULL)
if (!isRunning)
break;
- usleep(200000);
+ struct timespec ts = {0, 200000000};
+ nanosleep(&ts, NULL);
}
//after 5 seconds waiting thread still running. now killing it
//-----------------------------------------------------------------------------
void * DIVERT_CAP::Run(void * d)
{
-DIVERT_CAP * dc = (DIVERT_CAP *)d;
+sigset_t signalSet;
+sigfillset(&signalSet);
+pthread_sigmask(SIG_BLOCK, &signalSet, NULL);
+
+DIVERT_CAP * dc = static_cast<DIVERT_CAP *>(d);
dc->isRunning = true;
char buffer[64];
if (buffer[12] != 0x8)
continue;
- memcpy(rp.pckt, &buffer[14], pcktSize);
+ memcpy(rp.rawPacket.pckt, &buffer[14], pcktSize);
dc->traffCnt->Process(rp);
}
return 0;
}
//-----------------------------------------------------------------------------
-int DIVERT_CAP::ParseIntInRange(const std::string & str, int min, int max, int * val)
-{
-if (str2x(str.c_str(), *val))
- {
- errorStr = "Incorrect value \'" + str + "\'.";
- return -1;
- }
-if (*val < min || *val > max)
- {
- errorStr = "Value \'" + str + "\' out of range.";
- return -1;
- }
-return 0;
-}
-//-----------------------------------------------------------------------------
DIVERT_CAP();
virtual ~DIVERT_CAP() {}
- void SetUsers(USERS *) {}
- void SetTariffs(TARIFFS *) {}
- void SetAdmins(ADMINS *) {}
void SetTraffcounter(TRAFFCOUNTER * tc) { traffCnt = tc; }
- void SetStore(STORE *) {}
- void SetStgSettings(const SETTINGS *) {}
int Start();
int Stop();
uint16_t GetStopPosition() const { return 10; }
private:
+ DIVERT_CAP(const DIVERT_CAP & rvalue);
+ DIVERT_CAP & operator=(const DIVERT_CAP & rvalue);
+
static void * Run(void *);
int DivertCapOpen();
int DivertCapRead(char * buffer, int blen, char ** iface, int n);
int DivertCapClose();
- int ParseIntInRange(const std::string & str, int min, int max, int * val);
-
MODULE_SETTINGS settings;
int port;
SRCS = ./ether_cap.cpp
-STGLIBS = -lstgcommon
-
LIBS += $(LIB_THREAD)
+STGLIBS = common
+
include ../../Makefile.in
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>
-
-#include <errno.h>
#include <fcntl.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <signal.h>
#include <unistd.h>
-#include "ether_cap.h"
+#include <cerrno>
+#include <cstdio>
+#include <cstring>
+#include <cstdlib>
+#include <csignal>
+
#include "stg/common.h"
#include "stg/raw_ip_packet.h"
#include "stg/traffcounter.h"
+#include "stg/plugin_creator.h"
-//#define CAP_DEBUG 1
-//-----------------------------------------------------------------------------
-
-//-----------------------------------------------------------------------------
-class BPF_CAP_CREATOR {
-private:
- BPF_CAP * bpfc;
+#include "ether_cap.h"
-public:
- BPF_CAP_CREATOR()
- : bpfc(new BPF_CAP())
- {
- }
- ~BPF_CAP_CREATOR()
- {
- delete bpfc;
- }
+//#define CAP_DEBUG 1
- BPF_CAP * GetCapturer()
- {
- return bpfc;
- }
-};
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
-BPF_CAP_CREATOR bcc;
+PLUGIN_CREATOR<BPF_CAP> bcc;
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
PLUGIN * GetPlugin()
{
-return bcc.GetCapturer();
+return bcc.GetPlugin();
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
}
//-----------------------------------------------------------------------------
BPF_CAP::BPF_CAP()
- : nonstop(false),
+ : capSettings(),
+ errorStr(),
+ bpfData(),
+ polld(),
+ thread(),
+ nonstop(false),
isRunning(false),
capSock(-1),
+ settings(),
traffCnt(NULL)
{
}
if (!isRunning)
break;
- usleep(200000);
+ struct timespec ts = {0, 200000000};
+ nanosleep(&ts, NULL);
}
//after 5 seconds waiting thread still running. now killing it
//-----------------------------------------------------------------------------
void * BPF_CAP::Run(void * d)
{
-BPF_CAP * dc = (BPF_CAP *)d;
+sigset_t signalSet;
+sigfillset(&signalSet);
+pthread_sigmask(SIG_BLOCK, &signalSet, NULL);
+
+BPF_CAP * dc = static_cast<BPF_CAP *>(d);
dc->isRunning = true;
uint8_t hdr[96]; //68 + 14 + 4(size) + 9(SYS_IFACE) + 1(align to 4) = 96
while (dc->nonstop)
{
- dc->BPFCapRead((char*)&hdr, 68 + 14, &iface);
+ if (dc->BPFCapRead((char*)&hdr, 68 + 14, &iface))
+ continue;
if (!(hdr[12] == 0x8 && hdr[13] == 0x0))
- {
continue;
- }
dc->traffCnt->Process(*rpp);
}
{
if (polld[i].revents & POLLIN)
{
- BPFCapRead(buffer, blen, capIface, &bpfData[i]);
+ if (BPFCapRead(buffer, blen, capIface, &bpfData[i]))
+ {
+ polld[i].revents = 0;
+ continue;
+ }
polld[i].revents = 0;
return 0;
}
}
-return 0;
+return -1;
}
//-----------------------------------------------------------------------------
int BPF_CAP::BPFCapRead(char * buffer, int blen, char **, BPF_DATA * bd)
bd->r = read(bd->fd, bd->buffer, BUFF_LEN);
if (bd->r < 0)
{
- //printfd(__FILE__, " error read\n");
- usleep(20000);
+ struct timespec ts = {0, 20000000};
+ nanosleep(&ts, NULL);
+ return -1;
}
bd->p = bd->buffer;
BPF_CAP();
virtual ~BPF_CAP() {}
- void SetUsers(USERS *) {}
- void SetTariffs(TARIFFS *) {}
- void SetAdmins(ADMINS *) {}
void SetTraffcounter(TRAFFCOUNTER * tc) { traffCnt = tc; }
- void SetStore(STORE *) {}
- void SetStgSettings(const SETTINGS *) {}
int Start();
int Stop();
uint16_t GetStopPosition() const { return 10; }
private:
+ BPF_CAP(const BPF_CAP & rvalue);
+ BPF_CAP & operator=(const BPF_CAP & rvalue);
+
static void * Run(void *);
int BPFCapOpen();
int BPFCapOpen(BPF_DATA * bd);
PROG = mod_cap_ether.so
-SRCS = ./ether_cap.cpp
+SRCS = ./ether_cap.cpp
LIBS += $(LIB_THREAD)
-STGLIBS = -lstgcommon
+
+STGLIBS = common
include ../../Makefile.in
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/types.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
#include <unistd.h>
#include <linux/if_ether.h>
#include <linux/if_packet.h>
-#include <signal.h>
-
#include <sys/ioctl.h>
#include <net/if.h>
-#include "ether_cap.h"
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <cerrno>
+#include <csignal>
+
#include "stg/common.h"
#include "stg/raw_ip_packet.h"
#include "stg/traffcounter.h"
+#include "stg/plugin_creator.h"
-//#define CAP_DEBUG 1
-
-//-----------------------------------------------------------------------------
-class ETHER_CAP_CREATOR {
-private:
- ETHER_CAP * ec;
+#include "ether_cap.h"
-public:
- ETHER_CAP_CREATOR()
- : ec(new ETHER_CAP())
- {
- }
- ~ETHER_CAP_CREATOR()
- {
- delete ec;
- }
+//#define CAP_DEBUG 1
- ETHER_CAP * GetCapturer()
- {
- return ec;
- }
-};
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
-ETHER_CAP_CREATOR ecc;
+PLUGIN_CREATOR<ETHER_CAP> ecc;
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
PLUGIN * GetPlugin()
{
-return ecc.GetCapturer();
+return ecc.GetPlugin();
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
}
//-----------------------------------------------------------------------------
ETHER_CAP::ETHER_CAP()
- : nonstop(false),
+ : errorStr(),
+ thread(),
+ nonstop(false),
isRunning(false),
capSock(-1),
traffCnt(NULL)
//5 seconds to thread stops itself
for (int i = 0; i < 25 && isRunning; i++)
{
- usleep(200000);
+ struct timespec ts = {0, 200000000};
+ nanosleep(&ts, NULL);
}
//after 5 seconds waiting thread still running. now killing it
if (isRunning)
return -1;
}
for (int i = 0; i < 25 && isRunning; ++i)
- usleep(200000);
+ {
+ struct timespec ts = {0, 200000000};
+ nanosleep(&ts, NULL);
+ }
if (isRunning)
{
errorStr = "ETHER_CAP not stopped.";
//-----------------------------------------------------------------------------
void * ETHER_CAP::Run(void * d)
{
+sigset_t signalSet;
+sigfillset(&signalSet);
+pthread_sigmask(SIG_BLOCK, &signalSet, NULL);
+
ETHER_CAP * dc = (ETHER_CAP *)d;
dc->isRunning = true;
return 0;
}
-//-----------------------------------------------------------------------------
-bool ETHER_CAP::WaitPackets(int sd) const
-{
-fd_set rfds;
-FD_ZERO(&rfds);
-FD_SET(sd, &rfds);
-
-struct timeval tv;
-tv.tv_sec = 0;
-tv.tv_usec = 500000;
-
-int res = select(sd + 1, &rfds, NULL, NULL, &tv);
-if (res == -1) // Error
- {
- if (errno != EINTR)
- {
- printfd(__FILE__, "Error on select: '%s'\n", strerror(errno));
- }
- return false;
- }
-
-if (res == 0) // Timeout
- {
- return false;
- }
-
-return true;
-}
ETHER_CAP();
virtual ~ETHER_CAP() {}
- void SetUsers(USERS *) {}
- void SetTariffs(TARIFFS *) {}
- void SetAdmins(ADMINS *) {}
void SetTraffcounter(TRAFFCOUNTER * tc) { traffCnt = tc; }
- void SetStore(STORE *) {}
- void SetStgSettings(const SETTINGS *) {}
int Start();
int Stop();
int Reload() { return 0; }
bool IsRunning() { return isRunning; }
- void SetSettings(const MODULE_SETTINGS &) {}
int ParseSettings() { return 0; }
const std::string & GetStrError() const { return errorStr; }
const std::string GetVersion() const;
uint16_t GetStopPosition() const { return 10; }
private:
+ ETHER_CAP(const ETHER_CAP & rvalue);
+ ETHER_CAP & operator=(const ETHER_CAP & rvalue);
+
static void * Run(void *);
int EthCapOpen();
int EthCapClose();
int EthCapRead(void * buffer, int blen, char ** iface);
- bool WaitPackets(int sd) const;
mutable std::string errorStr;
./libipq.c
LIBS += $(LIB_THREAD)
-STGLIBS = -lstgcommon
+
+STGLIBS = common
include ../../Makefile.in
* Author : Boris Mikhailenko <stg34@stargazer.dp.ua>
*/
-#include <signal.h>
-#include <cerrno>
#include <netinet/in.h>
#include <linux/netfilter.h>
+#include <csignal>
+#include <cerrno>
+
#include "stg/raw_ip_packet.h"
#include "stg/traffcounter.h"
+#include "stg/plugin_creator.h"
+#include "stg/common.h"
+
#include "ipq_cap.h"
extern "C"
#include "libipq.h"
}
-class IPQ_CAP_CREATOR {
-private:
- IPQ_CAP * ic;
-
-public:
- IPQ_CAP_CREATOR()
- : ic(new IPQ_CAP())
- {
- }
- ~IPQ_CAP_CREATOR()
- {
- delete ic;
- }
-
- IPQ_CAP * GetCapturer()
- {
- return ic;
- }
-};
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
-IPQ_CAP_CREATOR icc;
+PLUGIN_CREATOR<IPQ_CAP> icc;
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
PLUGIN * GetPlugin()
{
-return icc.GetCapturer();
+return icc.GetPlugin();
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
IPQ_CAP::IPQ_CAP()
: ipq_h(NULL),
+ errorStr(),
+ thread(),
nonstop(false),
isRunning(false),
capSock(-1),
- traffCnt(NULL)
+ traffCnt(NULL),
+ buf()
{
memset(buf, 0, BUFSIZE);
}
{
if (!isRunning)
break;
- usleep(200000);
+ struct timespec ts = {0, 200000000};
+ nanosleep(&ts, NULL);
}
//after 5 seconds waiting thread still running. now killing it
if (isRunning)
}
for (int i = 0; i < 25 && isRunning; ++i)
{
- usleep(200000);
+ struct timespec ts = {0, 200000000};
+ nanosleep(&ts, NULL);
}
if (isRunning)
{
//-----------------------------------------------------------------------------
void * IPQ_CAP::Run(void * d)
{
+sigset_t signalSet;
+sigfillset(&signalSet);
+pthread_sigmask(SIG_BLOCK, &signalSet, NULL);
+
RAW_PACKET raw_packet;
-IPQ_CAP * dc = (IPQ_CAP *)d;
+IPQ_CAP * dc = static_cast<IPQ_CAP *>(d);
dc->isRunning = true;
memset(&raw_packet, 0, sizeof(raw_packet));
raw_packet.dataLen = -1;
IPQ_CAP();
virtual ~IPQ_CAP() {}
- void SetUsers(USERS *) {}
- void SetTariffs(TARIFFS *) {}
- void SetAdmins(ADMINS *) {}
void SetTraffcounter(TRAFFCOUNTER * tc) { traffCnt = tc; }
- void SetStore(STORE *) {}
- void SetStgSettings(const SETTINGS *) {}
int Start();
int Stop();
int Reload() { return 0; }
bool IsRunning() { return isRunning; }
- void SetSettings(const MODULE_SETTINGS &) {}
int ParseSettings() { return 0; }
const std::string & GetStrError() const { return errorStr; }
const std::string GetVersion() const;
uint16_t GetStopPosition() const { return 10; }
private:
+ IPQ_CAP(const IPQ_CAP & rvalue);
+ IPQ_CAP & operator=(const IPQ_CAP & rvalue);
+
static void * Run(void *);
int IPQCapOpen();
int IPQCapClose();
LIBS += -liconv
endif
-STGLIBS = -lstgcommon -lstglogger
+STGLIBS = common \
+ locker \
+ logger \
+ scriptexecuter
include ../../Makefile.in
ADMIN * admin;
-if (admins->FindAdmin(login, &admin))
+if (admins->Find(login, &admin))
{
structVal["result"] = xmlrpc_c::value_boolean(false);
*retvalPtr = xmlrpc_c::value_struct(structVal);
ADMIN * admin;
-if (admins->FindAdmin(adminInfo.admin, &admin))
+if (admins->Find(adminInfo.admin, &admin))
{
printfd(__FILE__, "METHOD_ADMIN_ADD::execute(): 'Invalid admin (logged)'\n");
*retvalPtr = xmlrpc_c::value_boolean(false);
ADMIN * admin;
-if (admins->FindAdmin(adminInfo.admin, &admin))
+if (admins->Find(adminInfo.admin, &admin))
{
*retvalPtr = xmlrpc_c::value_boolean(false);
return;
ADMIN * loggedAdmin;
-if (admins->FindAdmin(adminInfo.admin, &loggedAdmin))
+if (admins->Find(adminInfo.admin, &loggedAdmin))
{
*retvalPtr = xmlrpc_c::value_boolean(false);
return;
ADMIN * admin;
-if (admins->FindAdmin(login, &admin))
+if (admins->Find(login, &admin))
{
*retvalPtr = xmlrpc_c::value_boolean(false);
return;
void execute(xmlrpc_c::paramList const & paramList,
xmlrpc_c::value * const retvalPtr);
+
private:
+ METHOD_ADMIN_GET(const METHOD_ADMIN_GET & rvalue);
+ METHOD_ADMIN_GET & operator=(const METHOD_ADMIN_GET & rvalue);
+
RPC_CONFIG * config;
ADMINS * admins;
};
void execute(xmlrpc_c::paramList const & paramList,
xmlrpc_c::value * const retvalPtr);
+
private:
+ METHOD_ADMIN_ADD(const METHOD_ADMIN_ADD & rvalue);
+ METHOD_ADMIN_ADD & operator=(const METHOD_ADMIN_ADD & rvalue);
+
RPC_CONFIG * config;
ADMINS * admins;
};
void execute(xmlrpc_c::paramList const & paramList,
xmlrpc_c::value * const retvalPtr);
+
private:
+ METHOD_ADMIN_DEL(const METHOD_ADMIN_DEL & rvalue);
+ METHOD_ADMIN_DEL & operator=(const METHOD_ADMIN_DEL & rvalue);
+
RPC_CONFIG * config;
ADMINS * admins;
};
void execute(xmlrpc_c::paramList const & paramList,
xmlrpc_c::value * const retvalPtr);
+
private:
+ METHOD_ADMIN_CHG(const METHOD_ADMIN_CHG & rvalue);
+ METHOD_ADMIN_CHG & operator=(const METHOD_ADMIN_CHG & rvalue);
+
RPC_CONFIG * config;
ADMINS * admins;
};
void execute(xmlrpc_c::paramList const & paramList,
xmlrpc_c::value * const retvalPtr);
+
private:
+ METHOD_ADMINS_GET(const METHOD_ADMINS_GET & rvalue);
+ METHOD_ADMINS_GET & operator=(const METHOD_ADMINS_GET & rvalue);
+
RPC_CONFIG * config;
ADMINS * admins;
};
un += utsn.nodename;
structVal["version"] = xmlrpc_c::value_string(SERVER_VERSION);
-structVal["tariff_num"] = xmlrpc_c::value_int(tariffs->GetTariffsNum());
+structVal["tariff_num"] = xmlrpc_c::value_int(tariffs->Count());
structVal["tariff"] = xmlrpc_c::value_int(2);
-structVal["users_num"] = xmlrpc_c::value_int(users->GetUserNum());
+structVal["users_num"] = xmlrpc_c::value_int(users->Count());
structVal["uname"] = xmlrpc_c::value_string(un);
structVal["dir_num"] = xmlrpc_c::value_int(DIR_NUM);
structVal["day_fee"] = xmlrpc_c::value_int(dayFee);
void execute(xmlrpc_c::paramList const & paramList,
xmlrpc_c::value * const retvalP);
+
private:
+ METHOD_INFO(const METHOD_INFO & rvalue);
+ METHOD_INFO & operator=(const METHOD_INFO & rvalue);
+
TARIFFS * tariffs;
USERS * users;
size_t dayFee;
void execute(xmlrpc_c::paramList const & paramList,
xmlrpc_c::value * const retvalP);
+
private:
+ METHOD_LOGIN(const METHOD_LOGIN & rvalue);
+ METHOD_LOGIN & operator=(const METHOD_LOGIN & rvalue);
+
RPC_CONFIG * config;
};
void execute(xmlrpc_c::paramList const & paramList,
xmlrpc_c::value * const retvalP);
+
private:
+ METHOD_LOGOUT(const METHOD_LOGOUT & rvalue);
+ METHOD_LOGOUT & operator=(const METHOD_LOGOUT & rvalue);
+
RPC_CONFIG * config;
};
void execute(xmlrpc_c::paramList const & paramList,
xmlrpc_c::value * const retvalPtr);
+
private:
+ METHOD_MESSAGE_SEND(const METHOD_MESSAGE_SEND & rvalue);
+ METHOD_MESSAGE_SEND & operator=(const METHOD_MESSAGE_SEND & rvalue);
+
RPC_CONFIG * config;
USERS * users;
};
-#include <unistd.h> // TODO: usleep
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
#include <cstdlib>
#include <csignal>
-
+#include <cerrno>
+#include <cstring>
#include <vector>
#include <algorithm>
#include "stg/admin.h"
#include "stg/module_settings.h"
#include "stg/settings.h"
+#include "stg/plugin_creator.h"
#include "rpcconfig.h"
#include "info_methods.h"
#include "admins_methods.h"
#include "messages_methods.h"
-class RPC_CONFIG_CREATOR {
-private:
- RPC_CONFIG * rpcconfig;
-
-public:
- RPC_CONFIG_CREATOR()
- : rpcconfig(new RPC_CONFIG())
- {
- }
- ~RPC_CONFIG_CREATOR()
- {
- delete rpcconfig;
- }
-
- RPC_CONFIG * GetPlugin()
- {
- return rpcconfig;
- }
-};
-
-RPC_CONFIG_CREATOR rpcc;
+PLUGIN_CREATOR<RPC_CONFIG> rpcc;
RPC_CONFIG_SETTINGS::RPC_CONFIG_SETTINGS()
: errorStr(),
{
}
-int RPC_CONFIG_SETTINGS::ParseIntInRange(const std::string & str,
- int min,
- int max,
- int * val)
-{
-if (str2x(str.c_str(), *val))
- {
- errorStr = "Incorrect value \'" + str + "\'.";
- return -1;
- }
-if (*val < min || *val > max)
- {
- errorStr = "Value \'" + str + "\' out of range.";
- return -1;
- }
-return 0;
-}
-
int RPC_CONFIG_SETTINGS::ParseSettings(const MODULE_SETTINGS & s)
{
int p;
}
RPC_CONFIG::RPC_CONFIG()
- : users(NULL),
+ : errorStr(),
+ rpcConfigSettings(),
+ users(NULL),
admins(NULL),
tariffs(NULL),
store(NULL),
+ settings(),
+ fd(-1),
+ rpcRegistry(),
rpcServer(NULL),
running(false),
stopped(true),
- dayFee(0)
+ tid(),
+ cookies(),
+ dayFee(0),
+ dirNames()
{
}
{
InitiateRegistry();
running = true;
+
+fd = socket(AF_INET, SOCK_STREAM, 0);
+if (fd < 0)
+ {
+ errorStr = "Failed to create socket";
+ printfd(__FILE__, "Failed to create listening socket: %s\n", strerror(errno));
+ return -1;
+ }
+
+int flag = 1;
+
+if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag)))
+ {
+ errorStr = "Setsockopt failed.";
+ printfd(__FILE__, "Setsockopt failed: %s\n", strerror(errno));
+ return -1;
+ }
+
+struct sockaddr_in addr;
+addr.sin_family = AF_INET;
+addr.sin_port = htons(rpcConfigSettings.GetPort());
+addr.sin_addr.s_addr = inet_addr("0.0.0.0");
+
+if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)))
+ {
+ errorStr = "Failed to bind socket";
+ printfd(__FILE__, "Failed to bind listening socket: %s\n", strerror(errno));
+ return -1;
+ }
+
+if (listen(fd, 10))
+ {
+ errorStr = "Failed to listen socket";
+ printfd(__FILE__, "Failed to listen listening socket: %s\n", strerror(errno));
+ return -1;
+ }
+
rpcServer = new xmlrpc_c::serverAbyss(
- rpcRegistry,
- rpcConfigSettings.GetPort(),
- "/var/log/stargazer_rpc.log"
+ xmlrpc_c::serverAbyss::constrOpt()
+ .registryP(&rpcRegistry)
+ .logFileName("/var/log/stargazer_rpc.log")
+ .socketFd(fd)
);
+
if (pthread_create(&tid, NULL, Run, this))
{
errorStr = "Failed to create RPC thread";
printfd(__FILE__, "Failed to crate RPC thread\n");
return -1;
}
+
return 0;
}
{
running = false;
for (int i = 0; i < 5 && !stopped; ++i)
- usleep(200000);
-//rpcServer->terminate();
+ {
+ struct timespec ts = {0, 200000000};
+ nanosleep(&ts, NULL);
+ }
+
if (!stopped)
{
- if (pthread_kill(tid, SIGTERM))
- {
- errorStr = "Failed to kill thread";
- printfd(__FILE__, "Failed to kill thread\n");
- }
- for (int i = 0; i < 25 && !stopped; ++i)
- usleep(200000);
- if (!stopped)
- {
- printfd(__FILE__, "Failed to stop RPC thread\n");
- errorStr = "Failed to stop RPC thread";
- return -1;
- }
- else
- {
- pthread_join(tid, NULL);
- }
+ running = true;
+ printfd(__FILE__, "Failed to stop RPC thread\n");
+ errorStr = "Failed to stop RPC thread";
+ return -1;
+ }
+else
+ {
+ pthread_join(tid, NULL);
}
+
+close(fd);
+
return 0;
}
void * RPC_CONFIG::Run(void * rc)
{
+sigset_t signalSet;
+sigfillset(&signalSet);
+pthread_sigmask(SIG_BLOCK, &signalSet, NULL);
+
RPC_CONFIG * config = static_cast<RPC_CONFIG *>(rc);
config->stopped = false;
while (config->running)
{
- config->rpcServer->runOnce();
+ if (WaitPackets(config->fd))
+ config->rpcServer->runOnce();
}
config->stopped = true;
{
ADMIN * admin = NULL;
-if (!admins->AdminCorrect(login, password, &admin))
+if (!admins->Correct(login, password, &admin))
{
return true;
}
{
public:
RPC_CONFIG_SETTINGS();
- virtual ~RPC_CONFIG_SETTINGS() {};
- const std::string & GetStrError() const { return errorStr; };
+ virtual ~RPC_CONFIG_SETTINGS() {}
+ const std::string & GetStrError() const { return errorStr; }
int ParseSettings(const MODULE_SETTINGS & s);
- uint16_t GetPort() const { return port; };
- double GetCookieTimeout() const { return cookieTimeout; };
+ uint16_t GetPort() const { return port; }
+ double GetCookieTimeout() const { return cookieTimeout; }
+
private:
- int ParseIntInRange(const std::string & str,
- int min,
- int max,
- int * val);
std::string errorStr;
int port;
double cookieTimeout;
struct ADMIN_INFO
{
+ ADMIN_INFO()
+ : admin(),
+ accessTime(0),
+ priviledges()
+ {}
+
std::string admin;
time_t accessTime;
PRIV priviledges;
void SetTariffs(TARIFFS * t) { tariffs = t; }
void SetAdmins(ADMINS * a) { admins = a; }
void SetStore(STORE * s) { store = s; }
- void SetTraffcounter(TRAFFCOUNTER *) {}
void SetStgSettings(const SETTINGS * s);
void SetSettings(const MODULE_SETTINGS & s) { settings = s; }
int ParseSettings();
bool LogoutAdmin(const std::string & cookie);
private:
+ RPC_CONFIG(const RPC_CONFIG & rvalue);
+ RPC_CONFIG & operator=(const RPC_CONFIG & rvalue);
+
static void * Run(void *);
std::string GetCookie() const;
void InitiateRegistry();
TARIFFS * tariffs;
STORE * store;
MODULE_SETTINGS settings;
+ int fd;
xmlrpc_c::registry rpcRegistry;
xmlrpc_c::serverAbyss * rpcServer;
bool running;
ADMIN * admin;
-if (admins->FindAdmin(adminInfo.admin, &admin))
+if (admins->Find(adminInfo.admin, &admin))
{
*retvalPtr = xmlrpc_c::value_boolean(false);
return;
ADMIN * admin;
-if (admins->FindAdmin(adminInfo.admin, &admin))
+if (admins->Find(adminInfo.admin, &admin))
{
*retvalPtr = xmlrpc_c::value_boolean(false);
return;
ADMIN * admin;
-if (admins->FindAdmin(adminInfo.admin, &admin))
+if (admins->Find(adminInfo.admin, &admin))
{
*retvalPtr = xmlrpc_c::value_boolean(false);
return;
void execute(xmlrpc_c::paramList const & paramList,
xmlrpc_c::value * const retvalPtr);
+
private:
+ METHOD_TARIFF_GET(const METHOD_TARIFF_GET & rvalue);
+ METHOD_TARIFF_GET & operator=(const METHOD_TARIFF_GET & rvalue);
+
RPC_CONFIG * config;
TARIFFS * tariffs;
};
void execute(xmlrpc_c::paramList const & paramList,
xmlrpc_c::value * const retvalPtr);
+
private:
+ METHOD_TARIFF_CHG(const METHOD_TARIFF_CHG & rvalue);
+ METHOD_TARIFF_CHG & operator=(const METHOD_TARIFF_CHG & rvalue);
+
RPC_CONFIG * config;
ADMINS * admins;
TARIFFS * tariffs;
void execute(xmlrpc_c::paramList const & paramList,
xmlrpc_c::value * const retvalPtr);
+
private:
+ METHOD_TARIFFS_GET(const METHOD_TARIFFS_GET & rvalue);
+ METHOD_TARIFFS_GET & operator=(const METHOD_TARIFFS_GET & rvalue);
+
RPC_CONFIG * config;
TARIFFS * tariffs;
};
void execute(xmlrpc_c::paramList const & paramList,
xmlrpc_c::value * const retvalP);
+
private:
+ METHOD_TARIFF_ADD(const METHOD_TARIFF_ADD & rvalue);
+ METHOD_TARIFF_ADD & operator=(const METHOD_TARIFF_ADD & rvalue);
+
RPC_CONFIG * config;
ADMINS * admins;
TARIFFS * tariffs;
void execute(xmlrpc_c::paramList const & paramList,
xmlrpc_c::value * const retvalP);
+
private:
+ METHOD_TARIFF_DEL(const METHOD_TARIFF_DEL & rvalue);
+ METHOD_TARIFF_DEL & operator=(const METHOD_TARIFF_DEL & rvalue);
+
RPC_CONFIG * config;
ADMINS * admins;
TARIFFS * tariffs;
ADMIN * admin = NULL;
-if (admins->FindAdmin(adminInfo.admin, &admin))
+if (admins->Find(adminInfo.admin, &admin))
{
*retvalPtr = xmlrpc_c::value_boolean(false);
return;
ADMIN * admin;
-if (admins->FindAdmin(adminInfo.admin, &admin))
+if (admins->Find(adminInfo.admin, &admin))
{
*retvalPtr = xmlrpc_c::value_boolean(false);
return;
ADMIN * admin;
-if (admins->FindAdmin(adminInfo.admin, &admin))
+if (admins->Find(adminInfo.admin, &admin))
{
*retvalPtr = xmlrpc_c::value_boolean(false);
return;
ADMIN * admin;
-if (admins->FindAdmin(adminInfo.admin, &admin))
+if (admins->Find(adminInfo.admin, &admin))
{
*retvalPtr = xmlrpc_c::value_boolean(false);
return;
ADMIN * admin;
-if (admins->FindAdmin(adminInfo.admin, &admin))
+if (admins->Find(adminInfo.admin, &admin))
{
*retvalPtr = xmlrpc_c::value_boolean(false);
return;
ADMIN * admin;
-if (admins->FindAdmin(adminInfo.admin, &admin))
+if (admins->Find(adminInfo.admin, &admin))
{
*retvalPtr = xmlrpc_c::value_boolean(false);
return;
login,
store))
{
+ u->ResetNextTariff();
u->WriteConf();
*retvalPtr = xmlrpc_c::value_boolean(true);
return;
class TARIFFS;
class USERS;
class STORE;
-class IP_MASK;
+struct IP_MASK;
class METHOD_USER_GET : public xmlrpc_c::method {
public:
void execute(xmlrpc_c::paramList const & paramList,
xmlrpc_c::value * const retvalP);
+
private:
+ METHOD_USER_GET(const METHOD_USER_GET & rvalue);
+ METHOD_USER_GET & operator=(const METHOD_USER_GET & rvalue);
+
RPC_CONFIG * config;
USERS * users;
};
void execute(xmlrpc_c::paramList const & paramList,
xmlrpc_c::value * const retvalP);
+
private:
+ METHOD_USER_ADD(const METHOD_USER_ADD & rvalue);
+ METHOD_USER_ADD & operator=(const METHOD_USER_ADD & rvalue);
+
RPC_CONFIG * config;
ADMINS * admins;
USERS * users;
void execute(xmlrpc_c::paramList const & paramList,
xmlrpc_c::value * const retvalP);
+
private:
+ METHOD_USER_DEL(const METHOD_USER_DEL & rvalue);
+ METHOD_USER_DEL & operator=(const METHOD_USER_DEL & rvalue);
+
RPC_CONFIG * config;
ADMINS * admins;
USERS * users;
void execute(xmlrpc_c::paramList const & paramList,
xmlrpc_c::value * const retvalP);
+
private:
+ METHOD_USERS_GET(const METHOD_USERS_GET & rvalue);
+ METHOD_USERS_GET & operator=(const METHOD_USERS_GET & rvalue);
+
RPC_CONFIG * config;
USERS * users;
};
void execute(xmlrpc_c::paramList const & paramList,
xmlrpc_c::value * const retvalP);
+
private:
+ METHOD_USER_CHG(const METHOD_USER_CHG & rvalue);
+ METHOD_USER_CHG & operator=(const METHOD_USER_CHG & rvalue);
+
RPC_CONFIG * config;
ADMINS * admins;
TARIFFS * tariffs;
void execute(xmlrpc_c::paramList const & paramList,
xmlrpc_c::value * const retvalP);
+
private:
+ METHOD_USER_CASH_ADD(const METHOD_USER_CASH_ADD & rvalue);
+ METHOD_USER_CASH_ADD & operator=(const METHOD_USER_CASH_ADD & rvalue);
+
RPC_CONFIG * config;
ADMINS * admins;
STORE * store;
void execute(xmlrpc_c::paramList const & paramList,
xmlrpc_c::value * const retvalP);
+
private:
+ METHOD_USER_CASH_SET(const METHOD_USER_CASH_SET & rvalue);
+ METHOD_USER_CASH_SET & operator=(const METHOD_USER_CASH_SET & rvalue);
+
RPC_CONFIG * config;
ADMINS * admins;
STORE * store;
void execute(xmlrpc_c::paramList const & paramList,
xmlrpc_c::value * const retvalP);
+
private:
+ METHOD_USER_TARIFF_CHANGE(const METHOD_USER_TARIFF_CHANGE & rvalue);
+ METHOD_USER_TARIFF_CHANGE & operator=(const METHOD_USER_TARIFF_CHANGE & rvalue);
+
RPC_CONFIG * config;
ADMINS * admins;
TARIFFS * tariffs;
void execute(xmlrpc_c::paramList const & paramList,
xmlrpc_c::value * const retvalP);
+
private:
+ METHOD_GET_ONLINE_IPS(const METHOD_GET_ONLINE_IPS & rvalue);
+ METHOD_GET_ONLINE_IPS & operator=(const METHOD_GET_ONLINE_IPS & rvalue);
+
RPC_CONFIG * config;
USERS * users;
LIBS += -lexpat \
-lboost_thread-mt
-STGLIBS = -lstgcommon -lstglogger -lcrypto
+STGLIBS = common \
+ logger \
+ crypto
include ../../Makefile.in
+#include "stg/plugin_creator.h"
#include "stgconfig.h"
-class STGCONFIG_CREATOR
-{
-private:
- STGCONFIG2 * stgconfig;
-
-public:
- STGCONFIG_CREATOR()
- : stgconfig(new STGCONFIG2())
- {
- };
- ~STGCONFIG_CREATOR()
- {
- delete stgconfig;
- };
-
- STGCONFIG2 * GetPlugin()
- {
- return stgconfig;
- };
-};
-
-STGCONFIG_CREATOR stgc;
+PLUGIN_CREATOR<STGCONFIG2> stgc;
BASE_PLUGIN * GetPlugin()
{
void SetTariffs(TARIFFS * t) { tariffs = t; }
void SetAdmins(ADMINS * a) { admins = a; }
void SetStore(STORE * s) { store = s; }
- void SetTraffcounter(TRAFFCOUNTER *) {}
void SetStgSettings(const SETTINGS * s) { stgSettings = s; }
void SetSettings(const MODULE_SETTINGS & s) { modSettings = s; }
int ParseSettings();
LIBS += -lexpat \
$(LIB_THREAD)
-STGLIBS = -lstgcommon -lstglogger -lstgcrypto
+STGLIBS = common \
+ locker \
+ logger \
+ crypto \
+ scriptexecuter
include ../../Makefile.in
}
else
{
- for (unsigned int i = 0; i < cp->dataParser.size(); i++)
+ for (size_t i = 0; i < cp->dataParser.size(); i++)
{
cp->dataParser[i]->SetAnswerList(&cp->answerList);
cp->dataParser[i]->SetCurrAdmin(*cp->currAdmin);
}
else
{
- for (unsigned int i = 0; i < cp->dataParser.size(); i++)
+ for (size_t i = 0; i < cp->dataParser.size(); i++)
{
if (cp->dataParser[i]->ParseEnd(data, el) == 0)
{
}
//-----------------------------------------------------------------------------
CONFIGPROTO::CONFIGPROTO()
- : adminIP(0),
+ : answerList(),
+ requestList(),
+ adminIP(0),
+ adminLogin(),
port(0),
- nonstop(1),
+ thrReciveSendConf(),
+ nonstop(true),
state(0),
- currAdmin(),
+ currAdmin(NULL),
WriteServLog(GetStgLogger()),
- listenSocket(0),
+ listenSocket(-1),
+ parserGetServInfo(),
+ parserGetUsers(),
+ parserGetUser(),
+ parserChgUser(),
+ parserAddUser(),
+ parserDelUser(),
+ parserCheckUser(),
+ parserSendMessage(),
+ parserGetAdmins(),
+ parserAddAdmin(),
+ parserDelAdmin(),
+ parserChgAdmin(),
+ parserGetTariffs(),
+ parserAddTariff(),
+ parserDelTariff(),
+ parserChgTariff(),
admins(NULL),
- currParser(NULL)
+ currParser(NULL),
+ dataParser(),
+ xmlParser(),
+ errorStr()
{
dataParser.push_back(&parserGetServInfo);
void CONFIGPROTO::SetAdmins(ADMINS * a)
{
admins = a;
-for (unsigned int i = 0; i < dataParser.size(); i++)
+for (size_t i = 0; i < dataParser.size(); i++)
{
dataParser[i]->SetAdmins(a);
}
//-----------------------------------------------------------------------------
void CONFIGPROTO::SetUsers(USERS * u)
{
-for (unsigned int i = 0; i < dataParser.size(); i++)
+for (size_t i = 0; i < dataParser.size(); i++)
{
dataParser[i]->SetUsers(u);
}
//-----------------------------------------------------------------------------
void CONFIGPROTO::SetTariffs(TARIFFS * t)
{
-for (unsigned int i = 0; i < dataParser.size(); i++)
+for (size_t i = 0; i < dataParser.size(); i++)
{
dataParser[i]->SetTariffs(t);
}
//-----------------------------------------------------------------------------
void CONFIGPROTO::SetStore(STORE * s)
{
-for (unsigned int i = 0; i < dataParser.size(); i++)
+for (size_t i = 0; i < dataParser.size(); i++)
{
dataParser[i]->SetStore(s);
}
//-----------------------------------------------------------------------------
void CONFIGPROTO::SetStgSettings(const SETTINGS * s)
{
-for (unsigned int i = 0; i < dataParser.size(); i++)
+for (size_t i = 0; i < dataParser.size(); i++)
{
dataParser[i]->SetStgSettings(s);
}
}
//-----------------------------------------------------------------------------
-const string & CONFIGPROTO::GetStrError() const
-{
-return errorStr;
-}
-//-----------------------------------------------------------------------------
-uint32_t CONFIGPROTO::GetAdminIP() const
-{
-return adminIP;
-}
-//-----------------------------------------------------------------------------
void SetTariffs(TARIFFS * t);
void SetStore(STORE * s);
void SetStgSettings(const SETTINGS * s);
- uint32_t GetAdminIP() const;
+ uint32_t GetAdminIP() const { return adminIP; }
int Prepare();
int Stop();
- const std::string & GetStrError() const;
- static void * Run(void * a);
+ const std::string & GetStrError() const { return errorStr; }
+ void Run();
private:
+ CONFIGPROTO(const CONFIGPROTO & rvalue);
+ CONFIGPROTO & operator=(const CONFIGPROTO & rvalue);
+
int RecvHdr(int sock);
int RecvLogin(int sock);
- int SendLoginAnswer(int sock, int err);
+ int SendLoginAnswer(int sock);
int SendHdrAnswer(int sock, int err);
int RecvLoginS(int sock);
int SendLoginSAnswer(int sock, int err);
sprintf(s, "<version value=\"%s\"/>", SERVER_VERSION);
answerList->push_back(s);
-sprintf(s, "<tariff_num value=\"%d\"/>", tariffs->GetTariffsNum());
+sprintf(s, "<tariff_num value=\"%llu\"/>", (unsigned long long)tariffs->Count());
answerList->push_back(s);
sprintf(s, "<tariff value=\"%d\"/>", 2);
answerList->push_back(s);
-sprintf(s, "<users_num value=\"%d\"/>", users->GetUserNum());
+sprintf(s, "<users_num value=\"%llu\"/>", (unsigned long long)users->Count());
answerList->push_back(s);
sprintf(s, "<uname value=\"%s\"/>", un);
//-----------------------------------------------------------------------------
// GET USER
//-----------------------------------------------------------------------------
-PARSER_GET_USER::PARSER_GET_USER()
-{
-
-}
-//-----------------------------------------------------------------------------
int PARSER_GET_USER::ParseStart(void *, const char *el, const char **attr)
{
if (strcasecmp(el, "GetUser") == 0)
//-----------------------------------------------------------------------------
// GET USERS
//-----------------------------------------------------------------------------
-PARSER_GET_USERS::PARSER_GET_USERS()
- : lastUserUpdateTime(0),
- lastUpdateFound(false)
-{
-}
-//-----------------------------------------------------------------------------
int PARSER_GET_USERS::ParseStart(void *, const char *el, const char ** attr)
{
/*if (attr && *attr && *(attr+1))
//-----------------------------------------------------------------------------
// ADD USER
//-----------------------------------------------------------------------------
-PARSER_ADD_USER::PARSER_ADD_USER()
-{
-depth = 0;
-}
-//-----------------------------------------------------------------------------
int PARSER_ADD_USER::ParseStart(void *, const char *el, const char **attr)
{
depth++;
// PARSER CHG USER
//-----------------------------------------------------------------------------
PARSER_CHG_USER::PARSER_CHG_USER()
- : usr(NULL),
+ : BASE_PARSER(),
+ usr(NULL),
ucr(NULL),
upr(NULL),
downr(NULL),
+ cashMsg(),
+ login(),
cashMustBeAdded(false),
res(0)
{
class BASE_PARSER {
public:
BASE_PARSER()
- : admins(NULL),
+ : strError(),
+ admins(NULL),
users(NULL),
tariffs(NULL),
store(NULL),
currAdmin(NULL),
depth(0),
answerList(NULL)
- { }
+ {}
virtual ~BASE_PARSER() {}
virtual int ParseStart(void *data, const char *el, const char **attr) = 0;
virtual int ParseEnd(void *data, const char *el) = 0;
virtual void SetCurrAdmin(ADMIN & cua) { currAdmin = &cua; }
virtual std::string & GetStrError() { return strError; }
virtual void Reset() { answerList->clear(); depth = 0; }
+
protected:
+ BASE_PARSER(const BASE_PARSER & rvalue);
+ BASE_PARSER & operator=(const BASE_PARSER & rvalue);
+
std::string strError;
ADMINS * admins;
USERS * users;
//-----------------------------------------------------------------------------
class PARSER_ADD_ADMIN: public BASE_PARSER {
public:
- PARSER_ADD_ADMIN() : BASE_PARSER() {}
+ PARSER_ADD_ADMIN() : BASE_PARSER(), adminToAdd() {}
int ParseStart(void *data, const char *el, const char **attr);
int ParseEnd(void *data, const char *el);
void CreateAnswer();
//-----------------------------------------------------------------------------
class PARSER_DEL_ADMIN: public BASE_PARSER {
public:
- PARSER_DEL_ADMIN() : BASE_PARSER() {}
+ PARSER_DEL_ADMIN() : BASE_PARSER(), adminToDel() {}
int ParseStart(void *data, const char *el, const char **attr);
int ParseEnd(void *data, const char *el);
void CreateAnswer();
//-----------------------------------------------------------------------------
class PARSER_CHG_ADMIN: public BASE_PARSER {
public:
- PARSER_CHG_ADMIN() : BASE_PARSER() {}
+ PARSER_CHG_ADMIN() : BASE_PARSER(), login(), password(), privAsString() {}
int ParseStart(void *data, const char *el, const char **attr);
int ParseEnd(void *data, const char *el);
void CreateAnswer();
//-----------------------------------------------------------------------------
class PARSER_GET_USER: public BASE_PARSER {
public:
- PARSER_GET_USER();
- ~PARSER_GET_USER(){};
+ PARSER_GET_USER() : BASE_PARSER(), login() {}
+ ~PARSER_GET_USER() {}
int ParseStart(void *data, const char *el, const char **attr);
int ParseEnd(void *data, const char *el);
void CreateAnswer();
//-----------------------------------------------------------------------------
class PARSER_GET_USERS: public BASE_PARSER {
public:
- PARSER_GET_USERS();
+ PARSER_GET_USERS() : BASE_PARSER(), lastUserUpdateTime(0), lastUpdateFound(false) {}
int ParseStart(void *data, const char *el, const char **attr);
int ParseEnd(void *data, const char *el);
void CreateAnswer();
//-----------------------------------------------------------------------------
class PARSER_ADD_TARIFF: public BASE_PARSER {
public:
- PARSER_ADD_TARIFF() : BASE_PARSER() {}
+ PARSER_ADD_TARIFF() : BASE_PARSER(), tariffToAdd() {}
int ParseStart(void *data, const char *el, const char **attr);
int ParseEnd(void *data, const char *el);
void CreateAnswer();
//-----------------------------------------------------------------------------
class PARSER_DEL_TARIFF: public BASE_PARSER {
public:
- PARSER_DEL_TARIFF() : BASE_PARSER() {}
+ PARSER_DEL_TARIFF() : BASE_PARSER(), tariffToDel() {}
int ParseStart(void *data, const char *el, const char **attr);
int ParseEnd(void *data, const char *el);
void CreateAnswer();
//-----------------------------------------------------------------------------
class PARSER_CHG_TARIFF: public BASE_PARSER {
public:
- PARSER_CHG_TARIFF() : BASE_PARSER() {}
+ PARSER_CHG_TARIFF() : BASE_PARSER(), td() {}
int ParseStart(void *data, const char *el, const char **attr);
int ParseEnd(void *data, const char *el);
void CreateAnswer();
//-----------------------------------------------------------------------------/
class PARSER_ADD_USER: public BASE_PARSER {
public:
- PARSER_ADD_USER();
+ PARSER_ADD_USER() : BASE_PARSER(), login() {}
~PARSER_ADD_USER() {}
int ParseStart(void *data, const char *el, const char **attr);
int ParseEnd(void *data, const char *el);
void CreateAnswer();
void Reset();
private:
+ PARSER_CHG_USER(const PARSER_CHG_USER & rvalue);
+ PARSER_CHG_USER & operator=(const PARSER_CHG_USER & rvalue);
+
std::string EncChar2String(const char *);
int AplayChanges();
void CreateAnswer();
private:
+ PARSER_DEL_USER(const PARSER_DEL_USER & rvalue);
+ PARSER_DEL_USER & operator=(const PARSER_DEL_USER & rvalue);
+
int res;
USER * u;
};
//-----------------------------------------------------------------------------
class PARSER_SEND_MESSAGE: public BASE_PARSER {
public:
- PARSER_SEND_MESSAGE() : BASE_PARSER(), result(0), u(NULL) {}
+ PARSER_SEND_MESSAGE() : BASE_PARSER(), logins(), result(0), msg(), u(NULL) {}
int ParseStart(void *data, const char *el, const char **attr);
int ParseEnd(void *data, const char *el);
void CreateAnswer();
private:
+ PARSER_SEND_MESSAGE(const PARSER_SEND_MESSAGE & rvalue);
+ PARSER_SEND_MESSAGE & operator=(const PARSER_SEND_MESSAGE & rvalue);
+
int ParseLogins(const char * logins);
enum {res_ok, res_params_error, res_unknown};
*
*******************************************************************/
-#include <unistd.h> // cloase, usleep
+#include <unistd.h> // close
#include <cerrno>
#include <csignal>
return 0;
}
//-----------------------------------------------------------------------------
-// æÕÎËÃÉÑ ÏÂÝÅÎÉÑ Ó ËÏÎÆÉÇÕÒÁÔÏÒÏÍ
-void * CONFIGPROTO::Run(void * a)
+void CONFIGPROTO::Run()
{
-/*
- * Function Name:ReciveSendConf
- * Parameters: void * a ÕËÁÚÁÔÅÌØ ÎÁ ÜËÚÅÍÐÌÑÒ ËÌÁÓÓÁ CONFIGPROTO
- * Description: üÔÁ ÆÕÎËÃÉÑ ÏÂÅÓÐÅÞÉ×ÁÅÔ ÓÅÔÅ×ÏÅ ×ÚÁÉÍÏÄÅÊÓÔ×ÉÅ
- * Ó íÅÎÅÄÖÅÒÏÍ ëÌÉÅÎÔÏ×. ÷ ÅÅ ÚÁÄÁÞÉ ×ÈÏÄÉÔ: ÐÒÉÅÍ ÚÁÐÒÏÓÏ× ÐÏ TCP/IP
- * ÉÈ ÒÁÓÛÉÆÒÏ×ËÁ, ÐÅÒÅÄÁÞÁ ÐÒÉÎÑÔÙÈ ÄÁÎÎÙÈ ÁÎÁÌÉÚÁÔÏÒÕ É ÏÔÐÒÁ×ËÁ ÏÔ×ÅÔÁ ÎÁÚÁÄ.
- * Returns: ×ÏÚ×ÒÁÝÁÅÔ NULL
- */
-
-CONFIGPROTO * cp = (CONFIGPROTO*)a;
-cp->state = confHdr;
+state = confHdr;
-while (cp->nonstop)
+while (nonstop)
{
- cp->state = confHdr;
+ state = confHdr;
struct sockaddr_in outerAddr;
socklen_t outerAddrLen(sizeof(outerAddr));
- int outerSocket = accept(cp->listenSocket,
+ int outerSocket = accept(listenSocket,
(struct sockaddr*)(&outerAddr),
&outerAddrLen);
- if (!cp->nonstop)
+ if (!nonstop)
{
- continue;
+ break;
}
if (outerSocket == -1)
{
printfd(__FILE__, "accept failed\n");
- usleep(100000);
continue;
}
- cp->adminIP = *(unsigned int*)&(outerAddr.sin_addr);
+ adminIP = *(unsigned int*)&(outerAddr.sin_addr);
printfd(__FILE__, "Connection accepted from %s\n", inet_ntostring(outerAddr.sin_addr.s_addr).c_str());
- if (cp->state == confHdr)
+ if (state == confHdr)
{
- if (cp->RecvHdr(outerSocket) < 0)
+ if (RecvHdr(outerSocket) < 0)
{
close(outerSocket);
continue;
}
- if (cp->state == confLogin)
+ if (state == confLogin)
{
- if (cp->SendHdrAnswer(outerSocket, ans_ok) < 0)
+ if (SendHdrAnswer(outerSocket, ans_ok) < 0)
{
close(outerSocket);
continue;
}
-
- if (cp->RecvLogin(outerSocket) < 0)
+ if (RecvLogin(outerSocket) < 0)
{
close(outerSocket);
continue;
}
-
- if (cp->state == confLoginCipher)
+ if (state == confLoginCipher)
{
- if (cp->SendLoginAnswer(outerSocket, ans_ok) < 0)
+ if (SendLoginAnswer(outerSocket) < 0)
{
close(outerSocket);
continue;
}
- if (cp->RecvLoginS(outerSocket) < 0)
+ if (RecvLoginS(outerSocket) < 0)
{
close(outerSocket);
continue;
}
-
- if (cp->state == confData)
+ if (state == confData)
{
- if (cp->SendLoginSAnswer(outerSocket, ans_ok) < 0)
+ if (SendLoginSAnswer(outerSocket, ans_ok) < 0)
{
close(outerSocket);
continue;
}
- if (cp->RecvData(outerSocket) < 0)
+ if (RecvData(outerSocket) < 0)
{
close(outerSocket);
continue;
}
- cp->state = confHdr;
+ state = confHdr;
}
else
{
- if (cp->SendLoginSAnswer(outerSocket, ans_err) < 0)
+ if (SendLoginSAnswer(outerSocket, ans_err) < 0)
{
close(outerSocket);
continue;
}
- cp->WriteLogAccessFailed(cp->adminIP);
+ WriteLogAccessFailed(adminIP);
}
}
else
{
- cp->WriteLogAccessFailed(cp->adminIP);
+ WriteLogAccessFailed(adminIP);
}
}
else
{
- cp->WriteLogAccessFailed(cp->adminIP);
- if (cp->SendHdrAnswer(outerSocket, ans_err) < 0)
+ WriteLogAccessFailed(adminIP);
+ if (SendHdrAnswer(outerSocket, ans_err) < 0)
{
close(outerSocket);
continue;
}
else
{
- cp->WriteLogAccessFailed(cp->adminIP);
+ WriteLogAccessFailed(adminIP);
}
close(outerSocket);
}
-
-return NULL;
}
//-----------------------------------------------------------------------------
int CONFIGPROTO::RecvHdr(int sock)
{
char buf[sizeof(STG_HEADER)];
memset(buf, 0, sizeof(STG_HEADER));
-int ret;
-int stgHdrLen = strlen(STG_HEADER);
-for (int i = 0; i < stgHdrLen; i++)
+size_t stgHdrLen = sizeof(STG_HEADER) - 1; // Without 0-char
+size_t pos = 0;
+while (pos < stgHdrLen)
{
- ret = recv(sock, &buf[i], 1, 0);
- if (ret <= 0)
+ if (!WaitPackets(sock))
+ {
+ state = confHdr;
+ SendError("Bad request");
+ return -1;
+ }
+ int ret = recv(sock, &buf[pos], stgHdrLen - pos, 0);
+ if (ret < 0)
{
state = confHdr;
return -1;
}
+ pos += ret;
}
if (0 == strncmp(buf, STG_HEADER, strlen(STG_HEADER)))
//-----------------------------------------------------------------------------
int CONFIGPROTO::SendHdrAnswer(int sock, int err)
{
-int ret;
-
if (err)
{
- ret = send(sock, ERR_HEADER, sizeof(ERR_HEADER)-1, 0);
- if (ret < 0)
+ if (send(sock, ERR_HEADER, sizeof(ERR_HEADER) - 1, 0) < 0)
{
WriteServLog("send ERR_HEADER error in SendHdrAnswer.");
return -1;
}
else
{
- ret = send(sock, OK_HEADER, sizeof(OK_HEADER)-1, 0);
- if (ret < 0)
+ if (send(sock, OK_HEADER, sizeof(OK_HEADER) - 1, 0) < 0)
{
WriteServLog("send OK_HEADER error in SendHdrAnswer.");
return -1;
//-----------------------------------------------------------------------------
int CONFIGPROTO::RecvLogin(int sock)
{
-char login[ADM_LOGIN_LEN+1];
-int ret;
+char login[ADM_LOGIN_LEN + 1];
memset(login, 0, ADM_LOGIN_LEN + 1);
-ret = recv(sock, login, ADM_LOGIN_LEN, 0);
+size_t pos = 0;
+while (pos < ADM_LOGIN_LEN) {
+ if (!WaitPackets(sock))
+ {
+ state = confHdr;
+ return ENODATA;
+ }
-if (ret < 0)
- {
- // Error in network
- close(sock);
- state = confHdr;
- return ENODATA;
- }
+ int ret = recv(sock, &login[pos], ADM_LOGIN_LEN - pos, 0);
-if (ret < ADM_LOGIN_LEN)
- {
- // Error in protocol
- close(sock);
- state = confHdr;
- return ENODATA;
- }
+ if (ret < 0)
+ {
+ // Error in network
+ state = confHdr;
+ return ENODATA;
+ }
+
+ pos += ret;
+}
-if (admins->FindAdmin(login, &currAdmin))
+if (admins->Find(login, &currAdmin))
{
// Admin not found
- close(sock);
state = confHdr;
return ENODATA;
}
+
currAdmin->SetIP(adminIP);
adminLogin = login;
state = confLoginCipher;
return 0;
}
//-----------------------------------------------------------------------------
-int CONFIGPROTO::SendLoginAnswer(int sock, int)
+int CONFIGPROTO::SendLoginAnswer(int sock)
{
-int ret;
-
-ret = send(sock, OK_LOGIN, sizeof(OK_LOGIN)-1, 0);
-if (ret < 0)
+if (send(sock, OK_LOGIN, sizeof(OK_LOGIN) - 1, 0) < 0)
{
WriteServLog("Send OK_LOGIN error in SendLoginAnswer.");
return -1;
int CONFIGPROTO::RecvLoginS(int sock)
{
char loginS[ADM_LOGIN_LEN + 1];
-char login[ADM_LOGIN_LEN + 1];
-int ret;
-BLOWFISH_CTX ctx;
memset(loginS, 0, ADM_LOGIN_LEN + 1);
-int total = 0;
-
-while (total < ADM_LOGIN_LEN)
+size_t pos = 0;
+while (pos < ADM_LOGIN_LEN)
{
- ret = recv(sock, &loginS[total], ADM_LOGIN_LEN - total, 0);
+ if (!WaitPackets(sock))
+ {
+ state = confHdr;
+ return ENODATA;
+ }
+
+ int ret = recv(sock, &loginS[pos], ADM_LOGIN_LEN - pos, 0);
if (ret < 0)
{
// Network error
printfd(__FILE__, "recv error: '%s'\n", strerror(errno));
- close(sock);
state = confHdr;
return ENODATA;
}
- total += ret;
+ pos += ret;
}
-if (currAdmin->GetLogin() == "")
+if (currAdmin->GetLogin().empty())
{
state = confHdr;
return ENODATA;
}
+BLOWFISH_CTX ctx;
EnDecodeInit(currAdmin->GetPassword().c_str(), ADM_PASSWD_LEN, &ctx);
-for (int i = 0; i < ADM_LOGIN_LEN/8; i++)
+char login[ADM_LOGIN_LEN + 1];
+for (size_t i = 0; i < ADM_LOGIN_LEN / 8; i++)
{
- DecodeString(login + i*8, loginS + i*8, &ctx);
+ DecodeString(login + i * 8, loginS + i * 8, &ctx);
}
if (currAdmin == admins->GetNoAdmin())
//-----------------------------------------------------------------------------
int CONFIGPROTO::SendLoginSAnswer(int sock, int err)
{
-int ret;
-
if (err)
{
- ret = send(sock, ERR_LOGINS, sizeof(ERR_LOGINS)-1, 0);
- if (ret < 0)
+ if (send(sock, ERR_LOGINS, sizeof(ERR_LOGINS) - 1, 0) < 0)
{
WriteServLog("send ERR_LOGIN error in SendLoginAnswer.");
return -1;
}
else
{
- ret = send(sock, OK_LOGINS, sizeof(OK_LOGINS)-1, 0);
- if (ret < 0)
+ if (send(sock, OK_LOGINS, sizeof(OK_LOGINS) - 1, 0) < 0)
{
WriteServLog("send OK_LOGINS error in SendLoginSAnswer.");
return -1;
//-----------------------------------------------------------------------------
int CONFIGPROTO::RecvData(int sock)
{
-int ret;
-char bufferS[8];
-char buffer[9];
-
-buffer[8] = 0;
-
requestList.clear();
BLOWFISH_CTX ctx;
while (1)
{
- int total = 0;
bool done = false;
- while (total < 8)
+ char bufferS[8];
+ size_t pos = 0;
+ while (pos < sizeof(bufferS))
{
- ret = recv(sock, &bufferS[total], 8 - total, 0);
+ if (!WaitPackets(sock))
+ {
+ done = true;
+ break;
+ }
+
+ int ret = recv(sock, &bufferS[pos], sizeof(bufferS) - pos, 0);
if (ret < 0)
{
// Network error
- close(sock);
- return 0;
+ printfd(__FILE__, "recv error: '%s'\n", strerror(errno));
+ return -1;
}
- if (ret < 8)
+ if (ret == 0)
{
- if (memchr(buffer, 0, ret) != NULL)
- {
- done = true;
- break;
- }
+ done = true;
+ break;
}
- total += ret;
+ pos += ret;
}
+ char buffer[8];
+ buffer[7] = 0;
+
DecodeString(buffer, bufferS, &ctx);
- requestList.push_back(std::string(buffer, total));
+ requestList.push_back(std::string(buffer, pos));
- if (done || memchr(buffer, 0, total) != NULL)
+ if (done || memchr(buffer, 0, pos) != NULL)
{
- // ëÏÎÅà ÐÏÓÙÌËÉ
+ // End of data
if (ParseCommand())
{
SendError("Bad command");
char buffS[8];
int n = 0;
int k = 0;
-int ret = 0;
EnDecodeInit(currAdmin->GetPassword().c_str(), ADM_PASSWD_LEN, &ctx);
{
while ((*li).c_str()[k])
{
- buff[n%8] = (*li).c_str()[k];
+ buff[n % 8] = (*li).c_str()[k];
n++;
k++;
- if (n%8 == 0)
+ if (n % 8 == 0)
{
EncodeString(buffS, buff, &ctx);
- ret = send(sock, buffS, 8, 0);
+ int ret = send(sock, buffS, 8, 0);
if (ret < 0)
{
return -1;
return 0;
}
-buff[n%8] = 0;
+buff[n % 8] = 0;
EncodeString(buffS, buff, &ctx);
answerList.clear();
-#include <stdio.h>
#include <unistd.h>
-#include <signal.h>
+#include <csignal>
#include <algorithm>
#include "stg/tariffs.h"
#include "stg/admins.h"
#include "stg/users.h"
+#include "stg/plugin_creator.h"
#include "stgconfig.h"
-class STGCONFIG_CREATOR
-{
-private:
- STG_CONFIG * stgconfig;
-
-public:
- STGCONFIG_CREATOR()
- : stgconfig(new STG_CONFIG())
- {
- };
- ~STGCONFIG_CREATOR()
- {
- delete stgconfig;
- };
-
- STG_CONFIG * GetPlugin()
- {
- return stgconfig;
- };
-};
-//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
-STGCONFIG_CREATOR stgc;
//-----------------------------------------------------------------------------
+PLUGIN_CREATOR<STG_CONFIG> stgc;
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
-STG_CONFIG_SETTINGS::STG_CONFIG_SETTINGS()
- : port(0)
-{
-}
-//-----------------------------------------------------------------------------
-const std::string & STG_CONFIG_SETTINGS::GetStrError() const
-{
-return errorStr;
-}
-//-----------------------------------------------------------------------------
-int STG_CONFIG_SETTINGS::ParseIntInRange(const std::string & str, int min, int max, int * val)
-{
-if (str2x(str.c_str(), *val))
- {
- errorStr = "Incorrect value \'" + str + "\'.";
- return -1;
- }
-if (*val < min || *val > max)
- {
- errorStr = "Value \'" + str + "\' out of range.";
- return -1;
- }
-return 0;
-}
//-----------------------------------------------------------------------------
int STG_CONFIG_SETTINGS::ParseSettings(const MODULE_SETTINGS & s)
{
return 0;
}
//-----------------------------------------------------------------------------
-uint16_t STG_CONFIG_SETTINGS::GetPort() const
-{
-return port;
-}
-//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
PLUGIN * GetPlugin()
}
//-----------------------------------------------------------------------------
STG_CONFIG::STG_CONFIG()
- : nonstop(false),
+ : errorStr(),
+ stgConfigSettings(),
+ thread(),
+ nonstop(false),
isRunning(false),
+ config(),
users(NULL),
admins(NULL),
tariffs(NULL),
store(NULL),
+ settings(),
stgSettings(NULL)
{
}
//-----------------------------------------------------------------------------
-void STG_CONFIG::SetUsers(USERS * u)
-{
-users = u;
-}
-//-----------------------------------------------------------------------------
-void STG_CONFIG::SetTariffs(TARIFFS * t)
-{
-tariffs = t;
-}
-//-----------------------------------------------------------------------------
-void STG_CONFIG::SetAdmins(ADMINS * a)
-{
-admins = a;
-}
-//-----------------------------------------------------------------------------
-void STG_CONFIG::SetStore(STORE * s)
-{
-store = s;
-}
-//-----------------------------------------------------------------------------
-void STG_CONFIG::SetStgSettings(const SETTINGS * s)
-{
-stgSettings = s;
-}
-//-----------------------------------------------------------------------------
-void STG_CONFIG::SetSettings(const MODULE_SETTINGS & s)
-{
-settings = s;
-}
-//-----------------------------------------------------------------------------
int STG_CONFIG::ParseSettings()
{
int ret = stgConfigSettings.ParseSettings(settings);
return ret;
}
//-----------------------------------------------------------------------------
-const std::string & STG_CONFIG::GetStrError() const
-{
-return errorStr;
-}
-//-----------------------------------------------------------------------------
int STG_CONFIG::Start()
{
if (isRunning)
if (!isRunning)
break;
- usleep(200000);
+ struct timespec ts = {0, 200000000};
+ nanosleep(&ts, NULL);
}
-//after 5 seconds waiting thread still running. now killing it
if (isRunning)
- {
- //TODO pthread_cancel()
- if (pthread_kill(thread, SIGINT))
- {
- errorStr = "Cannot kill thread.";
- printfd(__FILE__, "Cannot kill thread\n");
- return -1;
- }
- printfd(__FILE__, "STG_CONFIG killed\n");
- }
+ return -1;
return 0;
}
//-----------------------------------------------------------------------------
-bool STG_CONFIG::IsRunning()
-{
-return isRunning;
-}
-//-----------------------------------------------------------------------------
void * STG_CONFIG::Run(void * d)
{
+sigset_t signalSet;
+sigfillset(&signalSet);
+pthread_sigmask(SIG_BLOCK, &signalSet, NULL);
+
STG_CONFIG * stgConf = (STG_CONFIG *)d;
stgConf->isRunning = true;
-stgConf->config.Run(&stgConf->config);
+stgConf->config.Run();
stgConf->isRunning = false;
return NULL;
}
//-----------------------------------------------------------------------------
-uint16_t STG_CONFIG::GetStartPosition() const
-{
-return 220;
-}
-//-----------------------------------------------------------------------------
-uint16_t STG_CONFIG::GetStopPosition() const
-{
-return 220;
-}
-//-----------------------------------------------------------------------------
-
-
class STG_CONFIG_SETTINGS {
public:
- STG_CONFIG_SETTINGS();
+ STG_CONFIG_SETTINGS() : errorStr(), port(0) {}
virtual ~STG_CONFIG_SETTINGS() {}
- const std::string & GetStrError() const;
+ const std::string & GetStrError() const { return errorStr; }
int ParseSettings(const MODULE_SETTINGS & s);
- uint16_t GetPort() const;
+ uint16_t GetPort() const { return port; }
private:
- int ParseIntInRange(const std::string & str, int min, int max, int * val);
std::string errorStr;
int port;
};
STG_CONFIG();
virtual ~STG_CONFIG(){};
- void SetUsers(USERS * u);
- void SetTariffs(TARIFFS * t);
- void SetAdmins(ADMINS * a);
- void SetStore(STORE * s);
- void SetTraffcounter(TRAFFCOUNTER *) {}
- void SetStgSettings(const SETTINGS * s);
- void SetSettings(const MODULE_SETTINGS & s);
+ void SetUsers(USERS * u) { users = u; }
+ void SetTariffs(TARIFFS * t) { tariffs = t; }
+ void SetAdmins(ADMINS * a) { admins = a; }
+ void SetStore(STORE * s) { store = s; }
+ void SetStgSettings(const SETTINGS * s) { stgSettings = s; }
+ void SetSettings(const MODULE_SETTINGS & s) { settings = s; }
int ParseSettings();
int Start();
int Stop();
int Reload() { return 0; }
- bool IsRunning();
+ bool IsRunning() { return isRunning; }
- const std::string & GetStrError() const;
+ const std::string & GetStrError() const { return errorStr; }
const std::string GetVersion() const;
- uint16_t GetStartPosition() const;
- uint16_t GetStopPosition() const;
+ uint16_t GetStartPosition() const { return 220; }
+ uint16_t GetStopPosition() const { return 220; }
private:
+ STG_CONFIG(const STG_CONFIG & rvalue);
+ STG_CONFIG & operator=(const STG_CONFIG & rvalue);
+
static void * Run(void *);
+
mutable std::string errorStr;
STG_CONFIG_SETTINGS stgConfigSettings;
pthread_t thread;
LIBS += -lexpat \
$(LIB_THREAD)
-STGLIBS = -lstgcommon -lstglogger
+STGLIBS = common \
+ logger
include ../../Makefile.in
#include <functional>
#include <algorithm>
+#include "stg/plugin_creator.h"
#include "stgconfig.h"
#include "../../../tariffs.h"
#include "../../../admins.h"
#include "../../../users.h"
-class STGCONFIG_CREATOR
-{
-private:
- STG_CONFIG * stgconfig;
-
-public:
- STGCONFIG_CREATOR()
- : stgconfig(new STG_CONFIG())
- {
- };
- ~STGCONFIG_CREATOR()
- {
- delete stgconfig;
- };
-
- STG_CONFIG * GetPlugin()
- {
- return stgconfig;
- };
-};
-
-STGCONFIG_CREATOR stgc;
+PLUGIN_CREATOR<STG_CONFIG> stgc;
BASE_PLUGIN * GetPlugin()
{
return errorStr;
}
-int STG_CONFIG_SETTINGS::ParseIntInRange(const string & str, int min, int max, int * val)
-{
-if (str2x(str.c_str(), *val))
- {
- errorStr = "Incorrect value \'" + str + "\'.";
- return -1;
- }
-if (*val < min || *val > max)
- {
- errorStr = "Value \'" + str + "\' out of range.";
- return -1;
- }
-return 0;
-}
-
int STG_CONFIG_SETTINGS::ParseSettings(const MODULE_SETTINGS & s)
{
int p;
int ParseSettings(const MODULE_SETTINGS & s);
uint16_t GetPort();
private:
- int ParseIntInRange(const string & str, int min, int max, int * val);
string errorStr;
int port;
};
void SetTariffs(TARIFFS * t) { tariffs = t; }
void SetAdmins(ADMINS * a) { admins = a; }
void SetStore(STORE * s) { store = s; }
- void SetTraffcounter(TRAFFCOUNTER *) {}
void SetStgSettings(const SETTINGS * s) { stgConfigSettings = s; }
void SetSettings(const MODULE_SETTINGS & s) { settings = s; }
int ParseSettings();
#include <unistd.h>
#include <signal.h>
+#include "stg/plugin_creator.h"
#include "xrconfig.h"
#include "../../../tariff2.h"
#include "../../../admins.h"
#include "../../../users.h"
-class XR_CONFIG_CREATOR
-{
-private:
- XR_CONFIG * xrconfig;
-
-public:
- XR_CONFIG_CREATOR()
- : xrconfig(new XR_CONFIG())
- {
- };
- ~XR_CONFIG_CREATOR()
- {
- delete xrconfig;
- };
-
- XR_CONFIG * GetPlugin()
- {
- return xrconfig;
- };
-};
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
-XRCONFIG_CREATOR xrc;
+PLUGIN_CREATOR<XR_CONFIG> xrc;
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+BASE_PLUGIN * GetPlugin()
+{
+return xrc.GetPlugin();
+}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
return errorStr;
}
//-----------------------------------------------------------------------------
-int XR_CONFIG_SETTINGS::ParseIntInRange(const string & str, int min, int max, int * val)
-{
-if (strtoi2(str.c_str(), *val))
- {
- errorStr = "Incorrect value \'" + str + "\'.";
- return -1;
- }
-if (*val < min || *val > max)
- {
- errorStr = "Value \'" + str + "\' out of range.";
- return -1;
- }
-return 0;
-}
-//-----------------------------------------------------------------------------
int XR_CONFIG_SETTINGS::ParseSettings(const MODULE_SETTINGS & s)
{
-/*int p;
-PARAM_VALUE pv;
-vector<PARAM_VALUE>::const_iterator pvi;
-
-pv.param = "Port";
-pvi = find(s.moduleParams.begin(), s.moduleParams.end(), pv);
-if (pvi == s.moduleParams.end())
- {
- errorStr = "Parameter \'Port\' not found.";
- return -1;
- }
-
-if (ParseIntInRange(pvi->value[0], 2, 65535, &p))
- {
- errorStr = "Cannot parse parameter \'Port\': " + errorStr;
- return -1;
- }
-port = p;*/
return 0;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
-BASE_PLUGIN * GetPlugin()
-{
-return xrc.GetPlugin();
-}
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
const string XR_CONFIG::GetVersion() const
{
return "XR_configurator v.0.01";
#include <string>
#include <pthread.h>
#include "base_plugin.h"
-//#include "common_settings.h"
#include "common.h"
-//#include "configproto.h"
using namespace std;
uint16_t GetPort();
private:
- int ParseIntInRange(const string & str, int min, int max, int * val);
string errorStr;
int port;
};
void SetTariffs(TARIFFS * t);
void SetAdmins(ADMINS * a);
void SetStore(BASE_STORE * s);
- void SetTraffcounter(TRAFFCOUNTER * tc){};
void SetStgSettings(const SETTINGS * s);
void SetSettings(const MODULE_SETTINGS & s);
int ParseSettings();
SRCS = ./ping.cpp
-STGLIBS = -lstgpinger -lstgcommon
+STGLIBS = pinger \
+ common \
+ locker \
+ logger \
+ scriptexecuter
include ../../Makefile.in
-#include <stdio.h>
-#include <signal.h>
-
+#include <cstdio>
+#include <cassert>
+#include <csignal>
#include <ctime>
#include <algorithm>
#include "stg/user.h"
#include "stg/locker.h"
#include "stg/user_property.h"
+#include "stg/plugin_creator.h"
#include "ping.h"
-class PING_CREATOR
-{
-private:
- PING * ping;
-
-public:
- PING_CREATOR()
- : ping(new PING())
- {
- };
- ~PING_CREATOR()
- {
- delete ping;
- };
-
- PING * GetPlugin()
- {
- return ping;
- };
-};
+PLUGIN_CREATOR<PING> pc;
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
-PING_CREATOR pc;
+PLUGIN * GetPlugin()
+{
+return pc.GetPlugin();
+}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
-PLUGIN * GetPlugin()
-{
-return pc.GetPlugin();
-}
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-PING_SETTINGS::PING_SETTINGS()
- : pingDelay(0)
-{
-}
-//-----------------------------------------------------------------------------
int PING_SETTINGS::ParseSettings(const MODULE_SETTINGS & s)
{
PARAM_VALUE pv;
return 0;
}
//-----------------------------------------------------------------------------
-int PING_SETTINGS::ParseIntInRange(const std::string & str, int min, int max, int * val)
-{
-if (str2x(str.c_str(), *val))
- {
- errorStr = "Incorrect value \'" + str + "\'.";
- return -1;
- }
-if (*val < min || *val > max)
- {
- errorStr = "Value \'" + str + "\' out of range.";
- return -1;
- }
-return 0;
-}
-//-----------------------------------------------------------------------------
PING::PING()
- : users(NULL),
+ : errorStr(),
+ pingSettings(),
+ settings(),
+ users(NULL),
+ usersList(),
+ thread(),
+ mutex(),
nonstop(false),
isRunning(false),
+ pinger(),
+ ChgCurrIPNotifierList(),
+ ChgIPNotifierList(),
onAddUserNotifier(*this),
onDelUserNotifier(*this)
{
pthread_mutex_destroy(&mutex);
}
//-----------------------------------------------------------------------------
-const std::string PING::GetVersion() const
-{
-return "Pinger v.1.01";
-}
-//-----------------------------------------------------------------------------
-void PING::SetSettings(const MODULE_SETTINGS & s)
-{
-settings = s;
-}
-//-----------------------------------------------------------------------------
int PING::ParseSettings()
{
int ret = pingSettings.ParseSettings(settings);
return ret;
}
//-----------------------------------------------------------------------------
-void PING::SetUsers(USERS * u)
-{
-users = u;
-}
-//-----------------------------------------------------------------------------
-const std::string & PING::GetStrError() const
-{
-return errorStr;
-}
-//-----------------------------------------------------------------------------
int PING::Start()
{
GetUsers();
nanosleep(&ts, NULL);
}
-//after 5 seconds waiting thread still running. now kill it
-if (isRunning)
- {
- printfd(__FILE__, "kill PING thread.\n");
- if (pthread_kill(thread, SIGINT))
- {
- errorStr = "Cannot kill PING thread.";
- printfd(__FILE__, "Cannot kill PING thread.\n");
- return -1;
- }
- printfd(__FILE__, "PING killed\n");
- }
-
users->DelNotifierUserAdd(&onAddUserNotifier);
users->DelNotifierUserDel(&onDelUserNotifier);
++users_iter;
}
+if (isRunning)
+ return -1;
+
return 0;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void * PING::Run(void * d)
{
-PING * ping = (PING *)d;
+sigset_t signalSet;
+sigfillset(&signalSet);
+pthread_sigmask(SIG_BLOCK, &signalSet, NULL);
+
+PING * ping = static_cast<PING *>(d);
ping->isRunning = true;
long delay = (10000000 * ping->pingSettings.GetPingDelay()) / 3 + 50000000;
return NULL;
}
//-----------------------------------------------------------------------------
-uint16_t PING::GetStartPosition() const
-{
-return 100;
-}
-//-----------------------------------------------------------------------------
-uint16_t PING::GetStopPosition() const
-{
-return 100;
-}
-//-----------------------------------------------------------------------------
void PING::SetUserNotifiers(USER_PTR u)
{
CHG_CURRIP_NOTIFIER_PING ChgCurrIPNotifier(*this, u);
USER_PTR u;
int h = users->OpenSearch();
-if (!h)
- {
- printfd(__FILE__, "users->OpenSearch() error\n");
- return;
- }
+assert(h && "USERS::OpenSearch is always correct");
while (users->SearchNext(h, &u) == 0)
{
//-----------------------------------------------------------------------------*/
class CHG_CURRIP_NOTIFIER_PING: public PROPERTY_NOTIFIER_BASE<uint32_t> {
public:
- CHG_CURRIP_NOTIFIER_PING(const PING & p, USER_PTR u) : user(u), ping(p) {}
+ CHG_CURRIP_NOTIFIER_PING(const PING & p, USER_PTR u)
+ : PROPERTY_NOTIFIER_BASE<uint32_t>(), user(u), ping(p) {}
+ CHG_CURRIP_NOTIFIER_PING(const CHG_CURRIP_NOTIFIER_PING & rvalue)
+ : PROPERTY_NOTIFIER_BASE<uint32_t>(),
+ user(rvalue.user), ping(rvalue.ping) {}
void Notify(const uint32_t & oldIP, const uint32_t & newIP);
USER_PTR GetUser() const { return user; }
private:
+ CHG_CURRIP_NOTIFIER_PING & operator=(const CHG_CURRIP_NOTIFIER_PING & rvalue);
+
USER_PTR user;
const PING & ping;
};
//-----------------------------------------------------------------------------
class CHG_IPS_NOTIFIER_PING: public PROPERTY_NOTIFIER_BASE<USER_IPS> {
public:
- CHG_IPS_NOTIFIER_PING(const PING & p, USER_PTR u) : user(u), ping(p) {}
+ CHG_IPS_NOTIFIER_PING(const PING & p, USER_PTR u)
+ : PROPERTY_NOTIFIER_BASE<USER_IPS>(), user(u), ping(p) {}
+ CHG_IPS_NOTIFIER_PING(const CHG_IPS_NOTIFIER_PING & rvalue)
+ : PROPERTY_NOTIFIER_BASE<USER_IPS>(),
+ user(rvalue.user), ping(rvalue.ping) {}
void Notify(const USER_IPS & oldIPS, const USER_IPS & newIPS);
USER_PTR GetUser() const { return user; }
private:
+ CHG_IPS_NOTIFIER_PING & operator=(const CHG_IPS_NOTIFIER_PING & rvalue);
+
USER_PTR user;
const PING & ping;
};
//-----------------------------------------------------------------------------
class ADD_USER_NONIFIER_PING: public NOTIFIER_BASE<USER_PTR> {
public:
- ADD_USER_NONIFIER_PING(PING & p) : ping(p) {}
+ ADD_USER_NONIFIER_PING(PING & p) : NOTIFIER_BASE<USER_PTR>(), ping(p) {}
virtual ~ADD_USER_NONIFIER_PING() {}
void Notify(const USER_PTR & user);
private:
+ ADD_USER_NONIFIER_PING(const ADD_USER_NONIFIER_PING & rvalue);
+ ADD_USER_NONIFIER_PING & operator=(const ADD_USER_NONIFIER_PING & rvalue);
+
PING & ping;
};
//-----------------------------------------------------------------------------
class DEL_USER_NONIFIER_PING: public NOTIFIER_BASE<USER_PTR> {
public:
- DEL_USER_NONIFIER_PING(PING & p) : ping(p) {}
+ DEL_USER_NONIFIER_PING(PING & p) : NOTIFIER_BASE<USER_PTR>(), ping(p) {}
virtual ~DEL_USER_NONIFIER_PING() {}
void Notify(const USER_PTR & user);
private:
+ DEL_USER_NONIFIER_PING(const DEL_USER_NONIFIER_PING & rvalue);
+ DEL_USER_NONIFIER_PING & operator=(const DEL_USER_NONIFIER_PING & rvalue);
+
PING & ping;
};
//-----------------------------------------------------------------------------
class PING_SETTINGS {
public:
- PING_SETTINGS();
+ PING_SETTINGS() : pingDelay(0), errorStr() {}
virtual ~PING_SETTINGS() {}
const std::string & GetStrError() const { return errorStr; }
int ParseSettings(const MODULE_SETTINGS & s);
int GetPingDelay() const { return pingDelay; }
private:
- int ParseIntInRange(const std::string & str, int min, int max, int * val);
-
int pingDelay;
mutable std::string errorStr;
};
PING();
virtual ~PING();
- void SetUsers(USERS * u);
- void SetTariffs(TARIFFS *) {}
- void SetAdmins(ADMINS *) {}
- void SetTraffcounter(TRAFFCOUNTER *) {}
- void SetStore(STORE *) {}
- void SetStgSettings(const SETTINGS *) {}
- void SetSettings(const MODULE_SETTINGS & s);
+ void SetUsers(USERS * u) { users = u; }
+ void SetSettings(const MODULE_SETTINGS & s) { settings = s; }
int ParseSettings();
int Start();
int Reload() { return 0; }
bool IsRunning();
- const std::string & GetStrError() const;
- const std::string GetVersion() const;
- uint16_t GetStartPosition() const;
- uint16_t GetStopPosition() const;
+ const std::string & GetStrError() const { return errorStr; }
+ const std::string GetVersion() const { return "Pinger v.1.01"; }
+ uint16_t GetStartPosition() const { return 100; }
+ uint16_t GetStopPosition() const { return 100; }
void AddUser(USER_PTR u);
void DelUser(USER_PTR u);
private:
+ PING(const PING & rvalue);
+ PING & operator=(const PING & rvalue);
+
void GetUsers();
void SetUserNotifiers(USER_PTR u);
void UnSetUserNotifiers(USER_PTR u);
USERS * users;
std::list<USER_PTR> usersList;
- /*
- ÍÙ ÄÏÌÖÎÙ ÐÅÒÅÐÒÏ×ÅÒÉÔØ ×ÏÚÍÏÖÎÏÓÔØ ÐÉÎÇÏ×ÁÎÉÑ ÀÚÅÒÁ ÐÒÉ ÉÚÍÅÎÅÎÉÉ
- ÓÌÅÄÕÀÝÉÈ ÅÇÏ ÐÁÒÁÍÅÔÒÏ×:
- - currIP
- - ips
- */
pthread_t thread;
pthread_mutex_t mutex;
bool nonstop;
SRCS = ./radius.cpp
-STGLIBS = -lstgcommon -lstgcrypto
+STGLIBS = common \
+ crypto \
+ logger \
+ locker \
+ scriptexecuter
include ../../Makefile.in
#include "stg/common.h"
#include "stg/user_conf.h"
#include "stg/user_property.h"
+#include "stg/plugin_creator.h"
#include "radius.h"
extern volatile const time_t stgTime;
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
-class RAD_CREATOR {
-private:
- RADIUS * rad;
-
-public:
- RAD_CREATOR()
- : rad(new RADIUS())
- {
- }
- ~RAD_CREATOR()
- {
- delete rad;
- }
-
- RADIUS * GetPlugin()
- {
- return rad;
- }
-};
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-RAD_CREATOR radc;
+PLUGIN_CREATOR<RADIUS> radc;
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
-int RAD_SETTINGS::ParseIntInRange(const std::string & str, int min, int max, int * val)
-{
-if (str2x(str.c_str(), *val))
- {
- errorStr = "Incorrect value \'" + str + "\'.";
- return -1;
- }
-if (*val < min || *val > max)
- {
- errorStr = "Value \'" + str + "\' out of range.";
- return -1;
- }
-return 0;
-}
-//-----------------------------------------------------------------------------
int RAD_SETTINGS::ParseServices(const std::vector<std::string> & str, std::list<std::string> * lst)
{
std::copy(str.begin(), str.end(), std::back_inserter(*lst));
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
RADIUS::RADIUS()
- : nonstop(false),
+ : ctx(),
+ errorStr(),
+ radSettings(),
+ settings(),
+ authServices(),
+ acctServices(),
+ sessions(),
+ nonstop(false),
isRunning(false),
users(NULL),
stgSettings(NULL),
store(NULL),
- sock(-1)
+ thread(),
+ mutex(),
+ sock(-1),
+ packet()
{
InitEncrypt(&ctx, "");
}
//-----------------------------------------------------------------------------
-void RADIUS::SetUsers(USERS * u)
-{
-users = u;
-}
-//-----------------------------------------------------------------------------
-void RADIUS::SetStgSettings(const SETTINGS * s)
-{
-stgSettings = s;
-}
-//-----------------------------------------------------------------------------
-void RADIUS::SetSettings(const MODULE_SETTINGS & s)
-{
-settings = s;
-}
-//-----------------------------------------------------------------------------
-void RADIUS::SetStore(STORE * s)
-{
-store = s;
-}
-//-----------------------------------------------------------------------------
int RADIUS::ParseSettings()
{
int ret = radSettings.ParseSettings(settings);
return ret;
}
//-----------------------------------------------------------------------------
-bool RADIUS::IsRunning()
-{
-return isRunning;
-}
-//-----------------------------------------------------------------------------
-const std::string RADIUS::GetVersion() const
-{
-return "RADIUS data access plugin v 0.6";
-}
-//-----------------------------------------------------------------------------
-uint16_t RADIUS::GetStartPosition() const
-{
-// Start before any authorizers!!!
-return 20;
-}
-//-----------------------------------------------------------------------------
-uint16_t RADIUS::GetStopPosition() const
-{
-return 20;
-}
-//-----------------------------------------------------------------------------
int RADIUS::PrepareNet()
{
sock = socket(AF_INET, SOCK_DGRAM, 0);
USER_PTR ui;
if (users->FindByName(it->second.userName, &ui))
{
- ui->Unauthorize(this);
+ users->Unauthorize(ui->GetLogin(), this);
}
}
sessions.erase(sessions.begin(), sessions.end());
//5 seconds to thread stops itself
for (int i = 0; i < 25 && isRunning; i++)
{
- usleep(200000);
- }
-
- //after 5 seconds waiting thread still running. now killing it
- if (isRunning)
- {
- if (pthread_kill(thread, SIGINT))
- {
- errorStr = "Cannot kill thread.";
- printfd(__FILE__, "Cannot kill thread\n");
- return -1;
- }
- printfd(__FILE__, "RADIUS::Stop killed Run\n");
+ struct timespec ts = {0, 200000000};
+ nanosleep(&ts, NULL);
}
}
+if (isRunning)
+ return -1;
+
return 0;
}
//-----------------------------------------------------------------------------
void * RADIUS::Run(void * d)
{
+sigset_t signalSet;
+sigfillset(&signalSet);
+pthread_sigmask(SIG_BLOCK, &signalSet, NULL);
+
RADIUS * rad = (RADIUS *)d;
RAD_PACKET packet;
while (rad->nonstop)
{
- if (!rad->WaitPackets(rad->sock))
+ if (!WaitPackets(rad->sock))
{
continue;
}
return -1;
}
USER_IPS ips = ui->GetProperty().ips;
- if (ui->Authorize(ips[0].ip, 0xffFFffFF, this))
+ if (!users->Authorize(ui->GetLogin(), ips[0].ip, 0xffFFffFF, this))
{
printfd(__FILE__, "RADIUS::ProcessAcctStartPacket cannot authorize user '%s'\n", packet->login);
packet->packetType = RAD_REJECT_PACKET;
sessions.erase(sid);
-ui->Unauthorize(this);
+users->Unauthorize(ui->GetLogin(), this);
packet->packetType = RAD_ACCEPT_PACKET;
return 0;
return CanAuthService(svc) || CanAcctService(svc);
}
//-----------------------------------------------------------------------------
-bool RADIUS::WaitPackets(int sd) const
-{
-fd_set rfds;
-FD_ZERO(&rfds);
-FD_SET(sd, &rfds);
-
-struct timeval tv;
-tv.tv_sec = 0;
-tv.tv_usec = 500000;
-
-int res = select(sd + 1, &rfds, NULL, NULL, &tv);
-if (res == -1) // Error
- {
- if (errno != EINTR)
- {
- printfd(__FILE__, "Error on select: '%s'\n", strerror(errno));
- }
- return false;
- }
-
-if (res == 0) // Timeout
- {
- return false;
- }
-
-return true;
-}
-//-----------------------------------------------------------------------------
inline
void InitEncrypt(BLOWFISH_CTX * ctx, const std::string & password)
{
//-----------------------------------------------------------------------------
class RAD_SETTINGS {
public:
- RAD_SETTINGS() : port(0) {}
+ RAD_SETTINGS()
+ : port(0), errorStr(), password(),
+ authServices(), acctServices()
+ {}
virtual ~RAD_SETTINGS() {}
const string & GetStrError() const { return errorStr; }
int ParseSettings(const MODULE_SETTINGS & s);
const std::list<string> & GetAcctServices() const { return acctServices; }
private:
- int ParseIntInRange(const std::string & str, int min, int max, int * val);
int ParseServices(const std::vector<std::string> & str, std::list<std::string> * lst);
uint16_t port;
};
//-----------------------------------------------------------------------------
struct RAD_SESSION {
+ RAD_SESSION() : userName(), serviceType() {}
std::string userName;
std::string serviceType;
};
class RADIUS :public AUTH {
public:
RADIUS();
- virtual ~RADIUS() {};
-
- void SetUsers(USERS * u);
- void SetTariffs(TARIFFS *) {}
- void SetAdmins(ADMINS *) {}
- void SetTraffcounter(TRAFFCOUNTER *) {}
- void SetStore(STORE * );
- void SetStgSettings(const SETTINGS * s);
- void SetSettings(const MODULE_SETTINGS & s);
+ virtual ~RADIUS() {}
+
+ void SetUsers(USERS * u) { users = u; }
+ void SetStore(STORE * s) { store = s; }
+ void SetStgSettings(const SETTINGS *) {}
+ void SetSettings(const MODULE_SETTINGS & s) { settings = s; }
int ParseSettings();
int Start();
int Stop();
int Reload() { return 0; }
- bool IsRunning();
+ bool IsRunning() { return isRunning; }
const std::string & GetStrError() const { return errorStr; }
- const std::string GetVersion() const;
- uint16_t GetStartPosition() const;
- uint16_t GetStopPosition() const;
+ const std::string GetVersion() const { return "RADIUS data access plugin v 0.6"; }
+ uint16_t GetStartPosition() const { return 20; }
+ uint16_t GetStopPosition() const { return 20; }
int SendMessage(const STG_MSG &, uint32_t) const { return 0; }
private:
+ RADIUS(const RADIUS & rvalue);
+ RADIUS & operator=(const RADIUS & rvalue);
+
static void * Run(void *);
int PrepareNet();
int FinalizeNet();
bool CanAcctService(const std::string & svc) const;
bool IsAllowedService(const std::string & svc) const;
- bool WaitPackets(int sd) const;
-
void PrintServices(const std::list<std::string> & svcs);
struct Printer : public unary_function<std::string, void>
SRCS = ./rscript.cpp \
./nrmap_parser.cpp
-STGLIBS = -lstgcommon -lstgcrypto
+STGLIBS = common \
+ crypto \
+ locker \
+ logger \
+ scriptexecuter
include ../../Makefile.in
#include "stg/common.h"
#include "nrmap_parser.h"
-NRMapParser::NRMapParser()
-{
-}
-
-NRMapParser::~NRMapParser()
-{
-}
-
bool NRMapParser::ReadFile(const std::string & fileName)
{
std::ifstream source(fileName.c_str());
struct NET_ROUTER
{
-uint32_t subnetIP;
-uint32_t subnetMask;
-std::vector<uint32_t> routers;
+ NET_ROUTER() : subnetIP(0), subnetMask(0), routers() {}
+ NET_ROUTER(const NET_ROUTER & rvalue)
+ : subnetIP(rvalue.subnetIP),
+ subnetMask(rvalue.subnetMask),
+ routers(rvalue.routers)
+ {}
+
+ uint32_t subnetIP;
+ uint32_t subnetMask;
+ std::vector<uint32_t> routers;
+
+ NET_ROUTER & operator=(const NET_ROUTER & rvalue)
+ {
+ subnetIP = rvalue.subnetIP;
+ subnetMask = rvalue.subnetMask;
+ routers = rvalue.routers;
+ return *this;
+ }
};
class NRMapParser {
public:
- NRMapParser();
- ~NRMapParser();
+ NRMapParser() : nrmap(), errorStr() {}
+ ~NRMapParser() {}
bool ReadFile(const std::string & fileName);
const std::vector<NET_ROUTER> & GetMap() const { return nrmap; };
const std::string & GetErrorStr() const { return errorStr; };
+
private:
+ NRMapParser(const NRMapParser & rvalue);
+ NRMapParser & operator=(const NRMapParser & rvalue);
+
std::vector<NET_ROUTER> nrmap;
mutable std::string errorStr;
#include "stg/common.h"
#include "stg/locker.h"
#include "stg/user_property.h"
+#include "stg/plugin_creator.h"
#include "rscript.h"
#include "ur_functor.h"
#include "send_functor.h"
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
-class RS_CREATOR
-{
-private:
- REMOTE_SCRIPT * rs;
-
-public:
- RS_CREATOR()
- : rs(new REMOTE_SCRIPT())
- {
- };
- ~RS_CREATOR()
- {
- delete rs;
- };
-
- REMOTE_SCRIPT * GetPlugin()
- {
- return rs;
- };
-};
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-RS_CREATOR rsc;
+PLUGIN_CREATOR<REMOTE_SCRIPT> rsc;
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
-RS_USER::RS_USER()
- : lastSentTime(0),
- user(NULL),
- shortPacketsCount(0)
-{
-}
-//-----------------------------------------------------------------------------
-RS_USER::RS_USER(const std::vector<uint32_t> & r, USER_PTR it)
- : lastSentTime(0),
- user(it),
- routers(r),
- shortPacketsCount(0)
+RS_USER & RS_USER::operator=(const RS_USER & rvalue)
{
+lastSentTime = rvalue.lastSentTime;
+user = rvalue.user;
+routers = rvalue.routers;
+shortPacketsCount = rvalue.shortPacketsCount;
+return *this;
}
//-----------------------------------------------------------------------------
RS_SETTINGS::RS_SETTINGS()
: sendPeriod(0),
- port(0)
+ port(0),
+ errorStr(),
+ netRouters(),
+ userParams(),
+ password(),
+ subnetFile()
{
}
//-----------------------------------------------------------------------------
-int RS_SETTINGS::ParseIntInRange(const string & str, int min, int max, int * val)
-{
-if (str2x(str.c_str(), *val))
- {
- errorStr = "Incorrect value \'" + str + "\'.";
- return -1;
- }
-if (*val < min || *val > max)
- {
- errorStr = "Value \'" + str + "\' out of range.";
- return -1;
- }
-return 0;
-}
-//-----------------------------------------------------------------------------
int RS_SETTINGS::ParseSettings(const MODULE_SETTINGS & s)
{
int p;
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
REMOTE_SCRIPT::REMOTE_SCRIPT()
- : sendPeriod(15),
+ : ctx(),
+ afterChgIPNotifierList(),
+ authorizedUsers(),
+ errorStr(),
+ rsSettings(),
+ settings(),
+ sendPeriod(15),
halfPeriod(8),
nonstop(false),
isRunning(false),
users(NULL),
+ netRouters(),
+ thread(),
+ mutex(),
sock(0),
onAddUserNotifier(*this),
onDelUserNotifier(*this)
//-----------------------------------------------------------------------------
void * REMOTE_SCRIPT::Run(void * d)
{
+sigset_t signalSet;
+sigfillset(&signalSet);
+pthread_sigmask(SIG_BLOCK, &signalSet, NULL);
+
REMOTE_SCRIPT * rs = static_cast<REMOTE_SCRIPT *>(d);
rs->isRunning = true;
//5 seconds to thread stops itself
for (int i = 0; i < 25 && isRunning; i++)
{
- usleep(200000);
- }
-
- //after 5 seconds waiting thread still running. now killing it
- if (isRunning)
- {
- if (pthread_kill(thread, SIGINT))
- {
- errorStr = "Cannot kill thread.";
- printfd(__FILE__, "Cannot kill thread\n");
- return -1;
- }
- printfd(__FILE__, "REMOTE_SCRIPT killed Run\n");
+ struct timespec ts = {0, 200000000};
+ nanosleep(&ts, NULL);
}
}
users->DelNotifierUserDel(&onDelUserNotifier);
users->DelNotifierUserAdd(&onAddUserNotifier);
+if (isRunning)
+ return -1;
+
return 0;
}
//-----------------------------------------------------------------------------
}
}
//-----------------------------------------------------------------------------
+#ifdef NDEBUG
+bool REMOTE_SCRIPT::PreparePacket(char * buf, size_t, uint32_t ip, RS_USER & rsu, bool forceDisconnect) const
+#else
bool REMOTE_SCRIPT::PreparePacket(char * buf, size_t bufSize, uint32_t ip, RS_USER & rsu, bool forceDisconnect) const
+#endif
{
RS_PACKET_HEADER packetHead;
//-----------------------------------------------------------------------------
class RS_ADD_USER_NONIFIER: public NOTIFIER_BASE<USER_PTR> {
public:
- RS_ADD_USER_NONIFIER(REMOTE_SCRIPT & r) : rs(r) {}
+ RS_ADD_USER_NONIFIER(REMOTE_SCRIPT & r)
+ : NOTIFIER_BASE<USER_PTR>(), rs(r) {}
virtual ~RS_ADD_USER_NONIFIER() {}
void Notify(const USER_PTR & user);
private:
+ RS_ADD_USER_NONIFIER(const RS_ADD_USER_NONIFIER & rvalue);
+ RS_ADD_USER_NONIFIER & operator=(const RS_ADD_USER_NONIFIER);
+
REMOTE_SCRIPT & rs;
};
//-----------------------------------------------------------------------------
class RS_DEL_USER_NONIFIER: public NOTIFIER_BASE<USER_PTR> {
public:
- RS_DEL_USER_NONIFIER(REMOTE_SCRIPT & r) : rs(r) {}
+ RS_DEL_USER_NONIFIER(REMOTE_SCRIPT & r)
+ : NOTIFIER_BASE<USER_PTR>(), rs(r) {}
virtual ~RS_DEL_USER_NONIFIER() {}
void Notify(const USER_PTR & user);
private:
+ RS_DEL_USER_NONIFIER(const RS_DEL_USER_NONIFIER & rvalue);
+ RS_DEL_USER_NONIFIER & operator=(const RS_DEL_USER_NONIFIER);
+
REMOTE_SCRIPT & rs;
};
//-----------------------------------------------------------------------------
-template <typename varParamType>
-class RS_CHG_AFTER_NOTIFIER: public PROPERTY_NOTIFIER_BASE<varParamType> {
+template <typename T>
+class RS_CHG_AFTER_NOTIFIER: public PROPERTY_NOTIFIER_BASE<T> {
public:
- RS_CHG_AFTER_NOTIFIER(REMOTE_SCRIPT & r, USER_PTR u) : user(u), rs(r) {}
- void Notify(const varParamType & oldValue, const varParamType & newValue);
- USER_PTR GetUser() {return user; }
+ RS_CHG_AFTER_NOTIFIER(REMOTE_SCRIPT & r, USER_PTR u)
+ : PROPERTY_NOTIFIER_BASE<T>(), user(u), rs(r) {}
+ RS_CHG_AFTER_NOTIFIER(const RS_CHG_AFTER_NOTIFIER<T> & rvalue)
+ : PROPERTY_NOTIFIER_BASE<T>(), user(rvalue.user), rs(rvalue.rs) {}
+ void Notify(const T & oldValue, const T & newValue);
+ USER_PTR GetUser() { return user; }
private:
+ RS_CHG_AFTER_NOTIFIER<T> & operator=(const RS_CHG_AFTER_NOTIFIER<T> & rvalue);
+
USER_PTR user;
REMOTE_SCRIPT & rs;
};
//-----------------------------------------------------------------------------
struct RS_USER {
-RS_USER();
-RS_USER(const std::vector<uint32_t> & r, USER_PTR it);
-
-time_t lastSentTime;
-USER_PTR user;
-std::vector<uint32_t> routers;
-int shortPacketsCount;
+ RS_USER()
+ : lastSentTime(0),
+ user(NULL),
+ routers(),
+ shortPacketsCount(0)
+ {}
+ RS_USER(const std::vector<uint32_t> & r, USER_PTR it)
+ : lastSentTime(0),
+ user(it),
+ routers(r),
+ shortPacketsCount(0)
+ {}
+ RS_USER(const RS_USER & rvalue)
+ : lastSentTime(rvalue.lastSentTime),
+ user(rvalue.user),
+ routers(rvalue.routers),
+ shortPacketsCount(rvalue.shortPacketsCount)
+ {}
+
+ RS_USER & operator=(const RS_USER & rvalue);
+
+ time_t lastSentTime;
+ USER_PTR user;
+ std::vector<uint32_t> routers;
+ int shortPacketsCount;
};
//-----------------------------------------------------------------------------
class RS_SETTINGS {
const std::string & GetMapFileName() const { return subnetFile; }
private:
- int ParseIntInRange(const std::string & str, int min, int max, int * val);
int sendPeriod;
uint16_t port;
string errorStr;
virtual ~REMOTE_SCRIPT();
void SetUsers(USERS * u) { users = u; }
- void SetTariffs(TARIFFS *) {}
- void SetAdmins(ADMINS *) {}
- void SetTraffcounter(TRAFFCOUNTER *) {}
- void SetStore(STORE *) {}
- void SetStgSettings(const SETTINGS *) {}
void SetSettings(const MODULE_SETTINGS & s) { settings = s; }
int ParseSettings();
void ChangedIP(USER_PTR u, uint32_t oldIP, uint32_t newIP);
private:
+ REMOTE_SCRIPT(const REMOTE_SCRIPT & rvalue);
+ REMOTE_SCRIPT & operator=(const REMOTE_SCRIPT & rvalue);
+
static void * Run(void *);
bool PrepareNet();
bool FinalizeNet();
//-----------------------------------------------------------------------------
inline void RS_ADD_USER_NONIFIER::Notify(const USER_PTR & user)
{
-printfd(__FILE__, "ADD_USER_NONIFIER\n");
rs.AddUser(user);
}
//-----------------------------------------------------------------------------
inline void RS_DEL_USER_NONIFIER::Notify(const USER_PTR & user)
{
-printfd(__FILE__, "DEL_USER_NONIFIER\n");
rs.DelUser(user);
}
//-----------------------------------------------------------------------------
--- /dev/null
+include ../../../../../Makefile.conf
+
+LIBS += $(LIB_THREAD)
+
+PROG = mod_smux.so
+
+SRCS = smux.cpp \
+ sensors.cpp \
+ tables.cpp \
+ handlers.cpp \
+ utils.cpp \
+ types.cpp
+
+STGLIBS = common \
+ smux \
+ logger \
+ locker \
+ scriptexecuter
+
+CFLAGS += -I ../../../../../stglibs/smux.lib/include/stg
+CXXFLAGS += -I ../../../../../stglibs/smux.lib/include/stg
+
+include ../../Makefile.in
--- /dev/null
+STG-MIB DEFINITIONS ::= BEGIN
+
+IMPORTS
+ enterprises,
+ MODULE-IDENTITY, OBJECT-TYPE,
+ Integer32 FROM SNMPv2-SMI
+ DisplayString FROM SNMPv2-TC;
+
+stgMIB MODULE-IDENTITY
+ LAST-UPDATED "201101060000Z"
+ ORGANIZATION "STG"
+ CONTACT-INFO
+ "Primary Contact: Maxim Mamontov
+ email: faust@stg.dp.ua"
+ DESCRIPTION
+ "This MIB module defines objects for Stargazer data."
+ REVISION "201101060000Z"
+ DESCRIPTION "Initial revision"
+ ::= { enterprises 38313 }
+
+stg24 OBJECT IDENTIFIER ::= { stgMIB 1 }
+
+users OBJECT IDENTIFIER ::= { stg24 1 }
+tariffs OBJECT IDENTIFIER ::= { stg24 2 }
+admins OBJECT IDENTIFIER ::= { stg24 3 }
+services OBJECT IDENTIFIER ::= { stg24 4 }
+corporations OBJECT IDENTIFIER ::= { stg24 5 }
+traffcounter OBJECT IDENTIFIER ::= { stg24 6 }
+
+totalUsers OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Total users registered in the billing"
+ DEFVAL { 0 }
+ ::= { users 1 }
+
+onlineUsers OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The number of currently online users"
+ DEFVAL { 0 }
+ ::= { users 2 }
+
+authorizedUsers OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The number of currently authorized users"
+ DEFVAL { 0 }
+ ::= { users 3 }
+
+alwaysOnlineUsers OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The number of users with 'always online' option"
+ DEFVAL { 0 }
+ ::= { users 4 }
+
+noCashUsers OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The number of users with negative cash"
+ DEFVAL { 0 }
+ ::= { users 5 }
+
+disabledDetailStatsUsers OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The number of users with disabled detail stats"
+ DEFVAL { 0 }
+ ::= { users 6 }
+
+disabledUsers OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The number of disabled users"
+ DEFVAL { 0 }
+ ::= { users 7 }
+
+passiveUsers OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The number of passive users"
+ DEFVAL { 0 }
+ ::= { users 8 }
+
+creditUsers OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The number of users with positive credit"
+ DEFVAL { 0 }
+ ::= { users 9 }
+
+freeMbUsers OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The number of users with positive freeMb"
+ DEFVAL { 0 }
+ ::= { users 10 }
+
+tariffChangeUsers OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The number of users changing tariff next month"
+ DEFVAL { 0 }
+ ::= { users 11 }
+
+totalTariffs OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Total tariffs registered in the billing"
+ DEFVAL { 0 }
+ ::= { tariffs 1 }
+
+tariffUsageTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF TariffUsageTable
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "The number of users by each tariff"
+ DEFVAL { 0 }
+ ::= { tariffs 2 }
+
+tariffUsageTableEntry OBJECT-TYPE
+ SYNTAX TariffUsageTable
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "A row describing a given tariff"
+ INDEX { tariffIndex }
+ ::= {tariffUsageTable 1 }
+
+TariffUsageTable ::= SEQUENCE {
+ tariffIndex Integer32,
+ tariffName DisplayString,
+ userCount Integer32
+}
+
+tariffIndex OBJECT-TYPE
+ SYNTAX Integer32 (0..255)
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "The id of the tariff this table describes."
+ ::= { tariffUsageTableEntry 1 }
+
+tariffName OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The name of the tariff this table describes."
+ ::= { tariffUsageTableEntry 2 }
+
+userCount OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The count fo users of the tariff this table describes."
+ ::= { tariffUsageTableEntry 3 }
+
+totalAdmins OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Total admins registered in the billing"
+ DEFVAL { 0 }
+ ::= { admins 1 }
+
+totalServices OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Total services registered in the billing"
+ DEFVAL { 0 }
+ ::= { services 1 }
+
+totalCorporations OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Total corporations registered in the billing"
+ DEFVAL { 0 }
+ ::= { corporations 1 }
+
+totalRules OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Total traffic classification rules described by rules file"
+ DEFVAL { 0 }
+ ::= { traffcounter 1 }
+
+END
--- /dev/null
+Количество пользователей всего в биллинге
+Количество пользователей онлайн
+Количество пользователей с отрицательный балансом
+Количество пользователей с всегда онлайн
+Количество пользователей по отношению к каждому из тарифов
+Количество пользователей по отношению к каждому UserData полю - ?
+Количество пользователей с отключенной детальной статистикой
+Количество отключенных пользователей
+Количество замороженных пользователей
+Количество пользователей, у которых есть кредит
+Количество пользователей, у которых есть предоплаченный трафик
+
+Количество тарифов
+Количество направлений
--- /dev/null
+#include <cassert>
+
+#include "stg/GetRequest-PDU.h"
+#include "stg/GetResponse-PDU.h"
+#include "stg/VarBindList.h"
+#include "stg/VarBind.h"
+
+#include "stg/common.h"
+
+#include "utils.h"
+#include "smux.h"
+
+#ifdef SMUX_DEBUG
+bool SMUX::CloseHandler(const SMUX_PDUs_t * pdus)
+{
+printfd(__FILE__, "SMUX::CloseHandler()\n");
+asn_fprint(stderr, &asn_DEF_SMUX_PDUs, pdus);
+return true;
+}
+#else
+bool SMUX::CloseHandler(const SMUX_PDUs_t *)
+{
+return true;
+}
+#endif
+
+#ifdef SMUX_DEBUG
+bool SMUX::RegisterResponseHandler(const SMUX_PDUs_t * pdus)
+{
+printfd(__FILE__, "SMUX::RegisterResponseHandler()\n");
+asn_fprint(stderr, &asn_DEF_SMUX_PDUs, pdus);
+return true;
+}
+#else
+bool SMUX::RegisterResponseHandler(const SMUX_PDUs_t *)
+{
+return true;
+}
+#endif
+
+bool SMUX::PDUsRequestHandler(const SMUX_PDUs_t * pdus)
+{
+#ifdef SMUX_DEBUG
+printfd(__FILE__, "SMUX::PDUsRequestHandler()\n");
+asn_fprint(stderr, &asn_DEF_SMUX_PDUs, pdus);
+#endif
+PDUsHandlers::iterator it;
+it = pdusHandlers.find(pdus->choice.pdus.present);
+if (it != pdusHandlers.end())
+ {
+ return (this->*(it->second))(&pdus->choice.pdus);
+ }
+else
+ {
+#ifdef SMUX_DEBUG
+ switch (pdus->present)
+ {
+ case PDUs_PR_NOTHING:
+ printfd(__FILE__, "SMUX::PDUsRequestHandler() - nothing\n");
+ break;
+ case PDUs_PR_get_response:
+ printfd(__FILE__, "SMUX::PDUsRequestHandler() - get response\n");
+ break;
+ case PDUs_PR_trap:
+ printfd(__FILE__, "SMUX::PDUsRequestHandler() - trap\n");
+ break;
+ default:
+ printfd(__FILE__, "SMUX::PDUsRequestHandler() - undefined\n");
+ }
+#endif
+ }
+return true;
+}
+
+#ifdef SMUX_DEBUG
+bool SMUX::CommitOrRollbackHandler(const SMUX_PDUs_t * pdus)
+{
+printfd(__FILE__, "SMUX::CommitOrRollbackHandler()\n");
+asn_fprint(stderr, &asn_DEF_SMUX_PDUs, pdus);
+return true;
+}
+#else
+bool SMUX::CommitOrRollbackHandler(const SMUX_PDUs_t *)
+{
+return true;
+}
+#endif
+
+bool SMUX::GetRequestHandler(const PDUs_t * pdus)
+{
+#ifdef SMUX_DEBUG
+printfd(__FILE__, "SMUX::GetRequestHandler()\n");
+asn_fprint(stderr, &asn_DEF_PDUs, pdus);
+#endif
+const GetRequest_PDU_t * getRequest = &pdus->choice.get_request;
+GetResponse_PDU_t * msg = static_cast<GetResponse_PDU_t *>(calloc(1, sizeof(GetResponse_PDU_t)));
+assert(msg && "Enought mempry to allocate GetResponse_PDU_t");
+VarBindList_t * varBindList = &msg->variable_bindings;
+
+long id = 0;
+asn_INTEGER2long(&getRequest->request_id, &id);
+asn_long2INTEGER(&msg->request_id, id);
+asn_long2INTEGER(&msg->error_status, 0);
+asn_long2INTEGER(&msg->error_index, 0);
+
+const VarBindList_t * vbl = &getRequest->variable_bindings;
+for (int i = 0; i < vbl->list.count; ++i)
+ {
+ VarBind_t * vb = getRequest->variable_bindings.list.array[i];
+ Sensors::iterator it;
+ it = sensors.find(OID(&vb->name));
+ if (it == sensors.end())
+ {
+ return SendGetResponseErrorPDU(sock, getRequest,
+ PDU__error_status_noSuchName, i);
+ }
+
+ VarBind_t * newVb = static_cast<VarBind_t *>(calloc(1, sizeof(VarBind_t)));
+ assert(newVb && "Enought mempry to allocate VarBind_t");
+
+ it->first.ToOID(&newVb->name);
+ it->second->GetValue(&newVb->value);
+
+ ASN_SEQUENCE_ADD(varBindList, newVb);
+ }
+
+bool res = SendGetResponsePDU(sock, msg);
+#ifdef SMUX_DEBUG
+asn_fprint(stderr, &asn_DEF_GetResponse_PDU, msg);
+#endif
+ASN_STRUCT_FREE(asn_DEF_GetResponse_PDU, msg);
+return res;
+}
+
+bool SMUX::GetNextRequestHandler(const PDUs_t * pdus)
+{
+#ifdef SMUX_DEBUG
+printfd(__FILE__, "SMUX::GetNextRequestHandler()\n");
+asn_fprint(stderr, &asn_DEF_PDUs, pdus);
+#endif
+const GetRequest_PDU_t * getRequest = &pdus->choice.get_request;
+GetResponse_PDU_t * msg = static_cast<GetResponse_PDU_t *>(calloc(1, sizeof(GetResponse_PDU_t)));
+assert(msg && "Enought mempry to allocate GetResponse_PDU_t");
+VarBindList_t * varBindList = &msg->variable_bindings;
+
+long id = 0;
+asn_INTEGER2long(&getRequest->request_id, &id);
+asn_long2INTEGER(&msg->request_id, id);
+asn_long2INTEGER(&msg->error_status, 0);
+asn_long2INTEGER(&msg->error_index, 0);
+
+const VarBindList_t * vbl = &getRequest->variable_bindings;
+for (int i = 0; i < vbl->list.count; ++i)
+ {
+ VarBind_t * vb = getRequest->variable_bindings.list.array[i];
+ Sensors::iterator it;
+ it = sensors.upper_bound(OID(&vb->name));
+ if (it == sensors.end())
+ {
+#ifdef SMUX_DEBUG
+ printfd(__FILE__, "SMUX::GetNextRequestHandler() - '%s' not found\n", OID(&vb->name).ToString().c_str());
+#endif
+ return SendGetResponseErrorPDU(sock, getRequest,
+ PDU__error_status_noSuchName, i);
+ }
+
+ VarBind_t * newVb = static_cast<VarBind_t *>(calloc(1, sizeof(VarBind_t)));
+ assert(newVb && "Enought mempry to allocate VarBind_t");
+
+ it->first.ToOID(&newVb->name);
+ it->second->GetValue(&newVb->value);
+
+ ASN_SEQUENCE_ADD(varBindList, newVb);
+ }
+
+bool res = SendGetResponsePDU(sock, msg);
+#ifdef SMUX_DEBUG
+asn_fprint(stderr, &asn_DEF_PDU, msg);
+#endif
+ASN_STRUCT_FREE(asn_DEF_GetResponse_PDU, msg);
+return res;
+}
+
+bool SMUX::SetRequestHandler(const PDUs_t * pdus)
+{
+#ifdef SMUX_DEBUG
+printfd(__FILE__, "SMUX::SetRequestHandler()\n");
+asn_fprint(stderr, &asn_DEF_PDUs, pdus);
+#endif
+return SendGetResponseErrorPDU(sock, &pdus->choice.set_request,
+ PDU__error_status_readOnly, 0);
+}
--- /dev/null
+#ifndef __PEN_H__
+#define __PEN_H__
+
+#define PEN_PREFIX ".1.3.6.1.4.1.38313"
+
+#endif
--- /dev/null
+#include <cassert>
+
+#include "stg/INTEGER.h"
+
+#include "stg/user.h"
+
+#include "sensors.h"
+
+bool UsersSensor::GetValue(ObjectSyntax_t * objectSyntax) const
+{
+int handle = users.OpenSearch();
+assert(handle && "USERS::OpenSearch is always correct");
+
+USER_PTR user;
+size_t count = 0;
+while (!users.SearchNext(handle, &user))
+ {
+ if (UserPredicate(user))
+ ++count;
+ }
+
+users.CloseSearch(handle);
+
+ValueToOS(count, objectSyntax);
+return true;
+}
+
+#ifdef DEBUG
+std::string UsersSensor::ToString() const
+{
+int handle = users.OpenSearch();
+assert(handle && "USERS::OpenSearch is always correct");
+
+USER_PTR user;
+size_t count = 0;
+while (!users.SearchNext(handle, &user))
+ {
+ if (UserPredicate(user))
+ ++count;
+ }
+
+users.CloseSearch(handle);
+
+std::string res;
+x2str(count, res);
+return res;
+}
+#endif
--- /dev/null
+#ifndef __SENSORS_H__
+#define __SENSORS_H__
+
+#include <map>
+
+#include "stg/users.h"
+#include "stg/tariffs.h"
+#include "stg/admins.h"
+#include "stg/services.h"
+#include "stg/corporations.h"
+#include "stg/traffcounter.h"
+#include "stg/user_property.h"
+
+#include "stg/ObjectSyntax.h"
+
+#include "value2os.h"
+#include "types.h"
+
+class Sensor {
+ public:
+ virtual ~Sensor() {}
+ virtual bool GetValue(ObjectSyntax_t * objectSyntax) const = 0;
+#ifdef DEBUG
+ virtual std::string ToString() const = 0;
+#endif
+};
+
+typedef std::map<OID, Sensor *> Sensors;
+
+class TotalUsersSensor : public Sensor {
+ public:
+ TotalUsersSensor(const USERS & u) : users(u) {}
+ virtual ~TotalUsersSensor() {}
+
+ bool GetValue(ObjectSyntax_t * objectSyntax) const
+ {
+ ValueToOS(users.Count(), objectSyntax);
+ return true;
+ }
+
+#ifdef DEBUG
+ std::string ToString() const
+ { std::string res; x2str(users.Count(), res); return res; }
+#endif
+
+ private:
+ const USERS & users;
+};
+
+class UsersSensor : public Sensor {
+ public:
+ UsersSensor(USERS & u) : users(u) {}
+ virtual ~UsersSensor() {}
+
+ bool GetValue(ObjectSyntax_t * objectSyntax) const;
+#ifdef DEBUG
+ std::string ToString() const;
+#endif
+
+ private:
+ USERS & users;
+
+ virtual bool UserPredicate(USER_PTR userPtr) const = 0;
+};
+
+class ConnectedUsersSensor : public UsersSensor {
+ public:
+ ConnectedUsersSensor(USERS & u) : UsersSensor(u) {}
+ virtual ~ConnectedUsersSensor() {}
+
+ private:
+ bool UserPredicate(USER_PTR userPtr) const
+ { return userPtr->GetConnected(); }
+};
+
+class AuthorizedUsersSensor : public UsersSensor {
+ public:
+ AuthorizedUsersSensor(USERS & u) : UsersSensor(u) {}
+ virtual ~AuthorizedUsersSensor() {}
+
+ private:
+ bool UserPredicate(USER_PTR userPtr) const
+ { return userPtr->GetAuthorized(); }
+};
+
+class AlwaysOnlineUsersSensor : public UsersSensor {
+ public:
+ AlwaysOnlineUsersSensor(USERS & u) : UsersSensor(u) {}
+ virtual ~AlwaysOnlineUsersSensor() {}
+
+ private:
+ bool UserPredicate(USER_PTR userPtr) const
+ { return userPtr->GetProperty().alwaysOnline; }
+};
+
+class NoCashUsersSensor : public UsersSensor {
+ public:
+ NoCashUsersSensor(USERS & u) : UsersSensor(u) {}
+ virtual ~NoCashUsersSensor() {}
+
+ private:
+ bool UserPredicate(USER_PTR userPtr) const
+ { return userPtr->GetProperty().cash < 0; }
+};
+
+class DisabledDetailStatsUsersSensor : public UsersSensor {
+ public:
+ DisabledDetailStatsUsersSensor(USERS & u) : UsersSensor(u) {}
+ virtual ~DisabledDetailStatsUsersSensor() {}
+
+ private:
+ bool UserPredicate(USER_PTR userPtr) const
+ { return userPtr->GetProperty().disabledDetailStat; }
+};
+
+class DisabledUsersSensor : public UsersSensor {
+ public:
+ DisabledUsersSensor(USERS & u) : UsersSensor(u) {}
+ virtual ~DisabledUsersSensor() {}
+
+ private:
+ bool UserPredicate(USER_PTR userPtr) const
+ { return userPtr->GetProperty().disabled; }
+};
+
+class PassiveUsersSensor : public UsersSensor {
+ public:
+ PassiveUsersSensor(USERS & u) : UsersSensor(u) {}
+ virtual ~PassiveUsersSensor() {}
+
+ private:
+ bool UserPredicate(USER_PTR userPtr) const
+ { return userPtr->GetProperty().passive; }
+};
+
+class CreditUsersSensor : public UsersSensor {
+ public:
+ CreditUsersSensor(USERS & u) : UsersSensor(u) {}
+ virtual ~CreditUsersSensor() {}
+
+ private:
+ bool UserPredicate(USER_PTR userPtr) const
+ { return userPtr->GetProperty().credit > 0; }
+};
+
+class FreeMbUsersSensor : public UsersSensor {
+ public:
+ FreeMbUsersSensor(USERS & u) : UsersSensor(u) {}
+ virtual ~FreeMbUsersSensor() {}
+
+ private:
+ bool UserPredicate(USER_PTR userPtr) const
+ { return userPtr->GetProperty().freeMb > 0; }
+};
+
+class TariffChangeUsersSensor : public UsersSensor {
+ public:
+ TariffChangeUsersSensor(USERS & u) : UsersSensor(u) {}
+ virtual ~TariffChangeUsersSensor() {}
+
+ private:
+ bool UserPredicate(USER_PTR userPtr) const
+ { return userPtr->GetProperty().nextTariff.ConstData().empty(); }
+};
+
+class TotalTariffsSensor : public Sensor {
+ public:
+ TotalTariffsSensor(const TARIFFS & t) : tariffs(t) {}
+ virtual ~TotalTariffsSensor() {}
+
+ bool GetValue(ObjectSyntax_t * objectSyntax) const
+ {
+ ValueToOS(tariffs.Count(), objectSyntax);
+ return true;
+ }
+
+#ifdef DEBUG
+ std::string ToString() const
+ { std::string res; x2str(tariffs.Count(), res); return res; }
+#endif
+
+ private:
+ const TARIFFS & tariffs;
+};
+
+class TotalAdminsSensor : public Sensor {
+ public:
+ TotalAdminsSensor(const ADMINS & a) : admins(a) {}
+ virtual ~TotalAdminsSensor() {}
+
+ bool GetValue(ObjectSyntax_t * objectSyntax) const
+ {
+ ValueToOS(admins.Count(), objectSyntax);
+ return true;
+ }
+
+#ifdef DEBUG
+ std::string ToString() const
+ { std::string res; x2str(admins.Count(), res); return res; }
+#endif
+
+ private:
+ const ADMINS & admins;
+};
+
+class TotalServicesSensor : public Sensor {
+ public:
+ TotalServicesSensor(const SERVICES & s) : services(s) {}
+ virtual ~TotalServicesSensor() {}
+
+ bool GetValue(ObjectSyntax_t * objectSyntax) const
+ {
+ ValueToOS(services.Count(), objectSyntax);
+ return true;
+ }
+
+#ifdef DEBUG
+ std::string ToString() const
+ { std::string res; x2str(services.Count(), res); return res; }
+#endif
+
+ private:
+ const SERVICES & services;
+};
+
+class TotalCorporationsSensor : public Sensor {
+ public:
+ TotalCorporationsSensor(const CORPORATIONS & c) : corporations(c) {}
+ virtual ~TotalCorporationsSensor() {}
+
+ bool GetValue(ObjectSyntax_t * objectSyntax) const
+ {
+ ValueToOS(corporations.Count(), objectSyntax);
+ return true;
+ }
+
+#ifdef DEBUG
+ std::string ToString() const
+ { std::string res; x2str(corporations.Count(), res); return res; }
+#endif
+
+ private:
+ const CORPORATIONS & corporations;
+};
+
+class TotalRulesSensor : public Sensor {
+ public:
+ TotalRulesSensor(const TRAFFCOUNTER & t) : traffcounter(t) {}
+ virtual ~TotalRulesSensor() {}
+
+ bool GetValue(ObjectSyntax_t * objectSyntax) const
+ {
+ ValueToOS(traffcounter.RulesCount(), objectSyntax);
+ return true;
+ }
+
+#ifdef DEBUG
+ std::string ToString() const
+ { std::string res; x2str(traffcounter.RulesCount(), res); return res; }
+#endif
+
+ private:
+ const TRAFFCOUNTER & traffcounter;
+};
+
+template <typename T>
+class ConstSensor : public Sensor {
+ public:
+ ConstSensor(const T & v) : value(v) {}
+ virtual ~ConstSensor() {}
+
+ bool GetValue(ObjectSyntax * objectSyntax) const
+ { return ValueToOS(value, objectSyntax); }
+
+#ifdef DEBUG
+ std::string ToString() const
+ { std::string res; x2str(value, res); return res; }
+#endif
+
+ private:
+ T value;
+};
+
+#ifdef DEBUG
+template <>
+inline
+std::string ConstSensor<std::string>::ToString() const
+{
+return value;
+}
+#endif
+
+#endif
--- /dev/null
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+
+#include <cstring>
+#include <cerrno>
+#include <ctime>
+#include <csignal>
+#include <cassert>
+
+#include <vector>
+#include <algorithm>
+#include <iterator>
+#include <stdexcept>
+#include <utility>
+
+#include "stg/common.h"
+#include "stg/plugin_creator.h"
+
+#include "smux.h"
+#include "utils.h"
+
+PLUGIN_CREATOR<SMUX> smc;
+
+PLUGIN * GetPlugin()
+{
+return smc.GetPlugin();
+}
+
+bool SPrefixLess(const Sensors::value_type & a,
+ const Sensors::value_type & b)
+{
+return a.first.PrefixLess(b.first);
+}
+
+SMUX_SETTINGS::SMUX_SETTINGS()
+ : errorStr(),
+ ip(0),
+ port(0),
+ password()
+{}
+
+int SMUX_SETTINGS::ParseSettings(const MODULE_SETTINGS & s)
+{
+PARAM_VALUE pv;
+std::vector<PARAM_VALUE>::const_iterator pvi;
+int p;
+
+pv.param = "Port";
+pvi = std::find(s.moduleParams.begin(), s.moduleParams.end(), pv);
+if (pvi == s.moduleParams.end())
+ {
+ errorStr = "Parameter \'Port\' not found.";
+ printfd(__FILE__, "Parameter 'Port' not found\n");
+ return -1;
+ }
+if (ParseIntInRange(pvi->value[0], 2, 65535, &p))
+ {
+ errorStr = "Cannot parse parameter \'Port\': " + errorStr;
+ printfd(__FILE__, "Cannot parse parameter 'Port'\n");
+ return -1;
+ }
+port = p;
+
+pv.param = "Password";
+pvi = std::find(s.moduleParams.begin(), s.moduleParams.end(), pv);
+if (pvi == s.moduleParams.end())
+ {
+ errorStr = "Parameter \'Password\' not found.";
+ printfd(__FILE__, "Parameter 'Password' not found\n");
+ password = "";
+ }
+else
+ {
+ password = pvi->value[0];
+ }
+
+pv.param = "Server";
+pvi = std::find(s.moduleParams.begin(), s.moduleParams.end(), pv);
+if (pvi == s.moduleParams.end())
+ {
+ errorStr = "Parameter \'Server\' not found.";
+ printfd(__FILE__, "Parameter 'Server' not found\n");
+ return -1;
+ }
+ip = inet_strington(pvi->value[0]);
+
+return 0;
+}
+
+SMUX::SMUX()
+ : PLUGIN(),
+ users(NULL),
+ tariffs(NULL),
+ admins(NULL),
+ services(NULL),
+ corporations(NULL),
+ traffcounter(NULL),
+ errorStr(),
+ smuxSettings(),
+ settings(),
+ thread(),
+ mutex(),
+ running(false),
+ stopped(true),
+ sock(-1),
+ smuxHandlers(),
+ pdusHandlers(),
+ sensors(),
+ tables(),
+ notifiers(),
+ addUserNotifier(*this),
+ delUserNotifier(*this),
+ addDelTariffNotifier(*this)
+{
+pthread_mutex_init(&mutex, NULL);
+
+smuxHandlers[SMUX_PDUs_PR_close] = &SMUX::CloseHandler;
+smuxHandlers[SMUX_PDUs_PR_registerResponse] = &SMUX::RegisterResponseHandler;
+smuxHandlers[SMUX_PDUs_PR_pdus] = &SMUX::PDUsRequestHandler;
+smuxHandlers[SMUX_PDUs_PR_commitOrRollback] = &SMUX::CommitOrRollbackHandler;
+
+pdusHandlers[PDUs_PR_get_request] = &SMUX::GetRequestHandler;
+pdusHandlers[PDUs_PR_get_next_request] = &SMUX::GetNextRequestHandler;
+pdusHandlers[PDUs_PR_set_request] = &SMUX::SetRequestHandler;
+}
+
+SMUX::~SMUX()
+{
+ {
+ Sensors::iterator it;
+ for (it = sensors.begin(); it != sensors.end(); ++it)
+ delete it->second;
+ }
+ {
+ Tables::iterator it;
+ for (it = tables.begin(); it != tables.end(); ++it)
+ delete it->second;
+ }
+printfd(__FILE__, "SMUX::~SMUX()\n");
+pthread_mutex_destroy(&mutex);
+}
+
+int SMUX::ParseSettings()
+{
+return smuxSettings.ParseSettings(settings);
+}
+
+int SMUX::Start()
+{
+assert(users != NULL && "users must not be NULL");
+assert(tariffs != NULL && "tariffs must not be NULL");
+assert(admins != NULL && "admins must not be NULL");
+assert(services != NULL && "services must not be NULL");
+assert(corporations != NULL && "corporations must not be NULL");
+assert(traffcounter != NULL && "traffcounter must not be NULL");
+
+if (PrepareNet())
+ return -1;
+
+// Users
+sensors[OID(".1.3.6.1.4.1.38313.1.1.1")] = new TotalUsersSensor(*users);
+sensors[OID(".1.3.6.1.4.1.38313.1.1.2")] = new ConnectedUsersSensor(*users);
+sensors[OID(".1.3.6.1.4.1.38313.1.1.3")] = new AuthorizedUsersSensor(*users);
+sensors[OID(".1.3.6.1.4.1.38313.1.1.4")] = new AlwaysOnlineUsersSensor(*users);
+sensors[OID(".1.3.6.1.4.1.38313.1.1.5")] = new NoCashUsersSensor(*users);
+sensors[OID(".1.3.6.1.4.1.38313.1.1.6")] = new DisabledDetailStatsUsersSensor(*users);
+sensors[OID(".1.3.6.1.4.1.38313.1.1.7")] = new DisabledUsersSensor(*users);
+sensors[OID(".1.3.6.1.4.1.38313.1.1.8")] = new PassiveUsersSensor(*users);
+sensors[OID(".1.3.6.1.4.1.38313.1.1.9")] = new CreditUsersSensor(*users);
+sensors[OID(".1.3.6.1.4.1.38313.1.1.10")] = new FreeMbUsersSensor(*users);
+sensors[OID(".1.3.6.1.4.1.38313.1.1.11")] = new TariffChangeUsersSensor(*users);
+// Tariffs
+sensors[OID(".1.3.6.1.4.1.38313.1.2.1")] = new TotalTariffsSensor(*tariffs);
+// Admins
+sensors[OID(".1.3.6.1.4.1.38313.1.3.1")] = new TotalAdminsSensor(*admins);
+// Services
+sensors[OID(".1.3.6.1.4.1.38313.1.4.1")] = new TotalServicesSensor(*services);
+// Corporations
+sensors[OID(".1.3.6.1.4.1.38313.1.5.1")] = new TotalCorporationsSensor(*corporations);
+// Traffcounter
+sensors[OID(".1.3.6.1.4.1.38313.1.6.1")] = new TotalRulesSensor(*traffcounter);
+
+// Table data
+tables[".1.3.6.1.4.1.38313.1.2.2"] = new TariffUsersTable(".1.3.6.1.4.1.38313.1.2.2", *tariffs, *users);
+
+UpdateTables();
+SetNotifiers();
+
+#ifdef SMUX_DEBUG
+Sensors::const_iterator it(sensors.begin());
+while (it != sensors.end())
+ {
+ printfd(__FILE__, "%s = %s\n",
+ it->first.ToString().c_str(),
+ it->second->ToString().c_str());
+ ++it;
+ }
+#endif
+
+if (!running)
+ {
+ if (pthread_create(&thread, NULL, Runner, this))
+ {
+ errorStr = "Cannot create thread.";
+ printfd(__FILE__, "Cannot create thread\n");
+ return -1;
+ }
+ }
+
+return 0;
+}
+
+int SMUX::Stop()
+{
+printfd(__FILE__, "SMUX::Stop() - Before\n");
+running = false;
+
+if (!stopped)
+ {
+ //5 seconds to thread stops itself
+ for (int i = 0; i < 25 && !stopped; i++)
+ {
+ struct timespec ts = {0, 200000000};
+ nanosleep(&ts, NULL);
+ }
+ }
+
+if (stopped)
+ pthread_join(thread, NULL);
+
+ResetNotifiers();
+
+ {
+ Tables::iterator it;
+ for (it = tables.begin(); it != tables.end(); ++it)
+ delete it->second;
+ }
+ {
+ Sensors::iterator it;
+ for (it = sensors.begin(); it != sensors.end(); ++it)
+ delete it->second;
+ }
+
+tables.erase(tables.begin(), tables.end());
+sensors.erase(sensors.begin(), sensors.end());
+
+close(sock);
+
+if (!stopped)
+ {
+ running = true;
+ return -1;
+ }
+
+printfd(__FILE__, "SMUX::Stop() - After\n");
+return 0;
+}
+
+int SMUX::Reload()
+{
+if (Stop())
+ return -1;
+if (Start())
+ return -1;
+return 0;
+}
+
+void * SMUX::Runner(void * d)
+{
+sigset_t signalSet;
+sigfillset(&signalSet);
+pthread_sigmask(SIG_BLOCK, &signalSet, NULL);
+
+SMUX * smux = static_cast<SMUX *>(d);
+
+smux->Run();
+
+return NULL;
+}
+
+void SMUX::Run()
+{
+stopped = true;
+if (!SendOpenPDU(sock))
+ return;
+if (!SendRReqPDU(sock))
+ return;
+running = true;
+stopped = false;
+
+while(running)
+ {
+ if (WaitPackets(sock))
+ {
+ SMUX_PDUs_t * pdus = RecvSMUXPDUs(sock);
+ if (pdus)
+ {
+ DispatchPDUs(pdus);
+ ASN_STRUCT_FREE(asn_DEF_SMUX_PDUs, pdus);
+ }
+ }
+ if (!running)
+ break;
+ }
+SendClosePDU(sock);
+stopped = true;
+}
+
+bool SMUX::PrepareNet()
+{
+sock = socket(AF_INET, SOCK_STREAM, 0);
+
+if (sock < 0)
+ {
+ errorStr = "Cannot create socket.";
+ printfd(__FILE__, "Cannot create socket\n");
+ return true;
+ }
+
+struct sockaddr_in addr;
+
+addr.sin_family = AF_INET;
+addr.sin_port = htons(smuxSettings.GetPort());
+addr.sin_addr.s_addr = smuxSettings.GetIP();
+
+if (connect(sock, reinterpret_cast<struct sockaddr *>(&addr), sizeof(addr)))
+ {
+ errorStr = "Cannot connect.";
+ printfd(__FILE__, "Cannot connect. Message: '%s'\n", strerror(errno));
+ return true;
+ }
+
+return false;
+}
+
+bool SMUX::DispatchPDUs(const SMUX_PDUs_t * pdus)
+{
+SMUXHandlers::iterator it;
+it = smuxHandlers.find(pdus->present);
+if (it != smuxHandlers.end())
+ {
+ return (this->*(it->second))(pdus);
+ }
+else
+ {
+#ifdef SMUX_DEBUG
+ switch (pdus->present)
+ {
+ case SMUX_PDUs_PR_NOTHING:
+ printfd(__FILE__, "PDUs: nothing\n");
+ break;
+ case SMUX_PDUs_PR_open:
+ printfd(__FILE__, "PDUs: open\n");
+ break;
+ case SMUX_PDUs_PR_registerRequest:
+ printfd(__FILE__, "PDUs: registerRequest\n");
+ break;
+ default:
+ printfd(__FILE__, "PDUs: undefined\n");
+ }
+ asn_fprint(stderr, &asn_DEF_SMUX_PDUs, pdus);
+#endif
+ }
+return false;
+}
+
+bool SMUX::UpdateTables()
+{
+Sensors newSensors;
+bool done = true;
+Tables::iterator it(tables.begin());
+while (it != tables.end())
+ {
+ try
+ {
+ it->second->UpdateSensors(newSensors);
+ }
+ catch (const std::runtime_error & ex)
+ {
+ printfd(__FILE__,
+ "SMUX::UpdateTables - failed to update table '%s': '%s'\n",
+ it->first.c_str(), ex.what());
+ done = false;
+ break;
+ }
+ ++it;
+ }
+if (!done)
+ {
+ Sensors::iterator it(newSensors.begin());
+ while (it != newSensors.end())
+ {
+ delete it->second;
+ ++it;
+ }
+ return false;
+ }
+
+it = tables.begin();
+while (it != tables.end())
+ {
+ std::pair<Sensors::iterator, Sensors::iterator> res;
+ res = std::equal_range(sensors.begin(),
+ sensors.end(),
+ std::pair<OID, Sensor *>(OID(it->first), NULL),
+ SPrefixLess);
+ Sensors::iterator sit(res.first);
+ while (sit != res.second)
+ {
+ delete sit->second;
+ ++sit;
+ }
+ sensors.erase(res.first, res.second);
+ ++it;
+ }
+
+sensors.insert(newSensors.begin(), newSensors.end());
+
+return true;
+}
+
+void SMUX::SetNotifier(USER_PTR userPtr)
+{
+notifiers.push_back(CHG_AFTER_NOTIFIER(*this, userPtr));
+userPtr->GetProperty().tariffName.AddAfterNotifier(¬ifiers.back());
+}
+
+void SMUX::UnsetNotifier(USER_PTR userPtr)
+{
+std::list<CHG_AFTER_NOTIFIER>::iterator it = notifiers.begin();
+while (it != notifiers.end())
+ {
+ if (it->GetUserPtr() == userPtr)
+ {
+ userPtr->GetProperty().tariffName.DelAfterNotifier(&(*it));
+ notifiers.erase(it);
+ break;
+ }
+ ++it;
+ }
+}
+
+void SMUX::SetNotifiers()
+{
+int h = users->OpenSearch();
+assert(h && "USERS::OpenSearch is always correct");
+
+USER_PTR u;
+while (!users->SearchNext(h, &u))
+ SetNotifier(u);
+
+users->CloseSearch(h);
+
+users->AddNotifierUserAdd(&addUserNotifier);
+users->AddNotifierUserDel(&delUserNotifier);
+
+tariffs->AddNotifierAdd(&addDelTariffNotifier);
+tariffs->AddNotifierDel(&addDelTariffNotifier);
+}
+
+void SMUX::ResetNotifiers()
+{
+tariffs->DelNotifierDel(&addDelTariffNotifier);
+tariffs->DelNotifierAdd(&addDelTariffNotifier);
+
+users->DelNotifierUserDel(&delUserNotifier);
+users->DelNotifierUserAdd(&addUserNotifier);
+
+std::list<CHG_AFTER_NOTIFIER>::iterator it = notifiers.begin();
+while (it != notifiers.end())
+ {
+ it->GetUserPtr()->GetProperty().tariffName.DelAfterNotifier(&(*it));
+ ++it;
+ }
+}
+
+void CHG_AFTER_NOTIFIER::Notify(const std::string &, const std::string &)
+{
+smux.UpdateTables();
+}
--- /dev/null
+#ifndef __SMUX_H__
+#define __SMUX_H__
+
+#include <pthread.h>
+
+#include <string>
+#include <map>
+#include <list>
+
+#include "stg/SMUX-PDUs.h"
+#include "stg/ObjectSyntax.h"
+
+#include "stg/os_int.h"
+#include "stg/plugin.h"
+#include "stg/module_settings.h"
+#include "stg/notifer.h"
+#include "stg/noncopyable.h"
+
+#include "sensors.h"
+#include "tables.h"
+#include "types.h"
+
+extern "C" PLUGIN * GetPlugin();
+
+class USER;
+class SETTINGS;
+class SMUX;
+class USERS;
+class TARIFFS;
+class SERVICES;
+class CORPORATIONS;
+class TRAFFCOUNTER;
+
+typedef bool (SMUX::*SMUXPacketHandler)(const SMUX_PDUs_t * pdus);
+typedef bool (SMUX::*PDUsHandler)(const PDUs_t * pdus);
+typedef std::map<SMUX_PDUs_PR, SMUXPacketHandler> SMUXHandlers;
+typedef std::map<PDUs_PR, PDUsHandler> PDUsHandlers;
+//-----------------------------------------------------------------------------
+class SMUX_SETTINGS {
+public:
+ SMUX_SETTINGS();
+ virtual ~SMUX_SETTINGS() {}
+ const std::string & GetStrError() const { return errorStr; }
+ int ParseSettings(const MODULE_SETTINGS & s);
+
+ uint32_t GetIP() const { return ip; }
+ uint16_t GetPort() const { return port; }
+ const std::string GetPassword() const { return password; }
+
+private:
+ mutable std::string errorStr;
+
+ uint32_t ip;
+ uint16_t port;
+ std::string password;
+};
+//-----------------------------------------------------------------------------
+class CHG_AFTER_NOTIFIER : public PROPERTY_NOTIFIER_BASE<std::string> {
+public:
+ CHG_AFTER_NOTIFIER(SMUX & s, const USER_PTR & u)
+ : PROPERTY_NOTIFIER_BASE<std::string>(),
+ smux(s), userPtr(u) {}
+ CHG_AFTER_NOTIFIER(const CHG_AFTER_NOTIFIER & rvalue)
+ : PROPERTY_NOTIFIER_BASE<std::string>(),
+ smux(rvalue.smux), userPtr(rvalue.userPtr) {}
+ void Notify(const std::string &, const std::string &);
+
+ USER_PTR GetUserPtr() { return userPtr; }
+
+private:
+ CHG_AFTER_NOTIFIER & operator=(const CHG_AFTER_NOTIFIER & rvalue);
+ SMUX & smux;
+ USER_PTR userPtr;
+};
+//-----------------------------------------------------------------------------
+class ADD_DEL_TARIFF_NOTIFIER : public NOTIFIER_BASE<TARIFF_DATA>, private NONCOPYABLE {
+public:
+ ADD_DEL_TARIFF_NOTIFIER(SMUX & s)
+ : NOTIFIER_BASE<TARIFF_DATA>(), smux(s) {}
+ void Notify(const TARIFF_DATA &);
+
+private:
+ SMUX & smux;
+};
+//-----------------------------------------------------------------------------
+class ADD_USER_NOTIFIER : public NOTIFIER_BASE<USER_PTR>, private NONCOPYABLE {
+public:
+ ADD_USER_NOTIFIER(SMUX & s) : NOTIFIER_BASE<USER_PTR>(), smux(s) {}
+ void Notify(const USER_PTR &);
+
+private:
+ SMUX & smux;
+};
+//-----------------------------------------------------------------------------
+class DEL_USER_NOTIFIER : public NOTIFIER_BASE<USER_PTR>, private NONCOPYABLE {
+public:
+ DEL_USER_NOTIFIER(SMUX & s) : NOTIFIER_BASE<USER_PTR>(), smux(s) {}
+ void Notify(const USER_PTR &);
+
+private:
+ SMUX & smux;
+};
+//-----------------------------------------------------------------------------
+class SMUX : public PLUGIN {
+public:
+ SMUX();
+ virtual ~SMUX();
+
+ void SetUsers(USERS * u) { users = u; }
+ void SetTariffs(TARIFFS * t) { tariffs = t; }
+ void SetAdmins(ADMINS * a) { admins = a; }
+ void SetServices(SERVICES * s) { services = s; }
+ void SetTraffcounter(TRAFFCOUNTER * tc) { traffcounter = tc; }
+ void SetCorporations(CORPORATIONS * c) { corporations = c; }
+ void SetSettings(const MODULE_SETTINGS & s) { settings = s; }
+ int ParseSettings();
+
+ int Start();
+ int Stop();
+ int Reload();
+ bool IsRunning() { return running && !stopped; }
+
+ const std::string & GetStrError() const { return errorStr; }
+ const std::string GetVersion() const { return "Stg SMUX Plugin 1.1"; }
+ uint16_t GetStartPosition() const { return 100; }
+ uint16_t GetStopPosition() const { return 100; }
+
+ bool UpdateTables();
+
+ void SetNotifier(USER_PTR userPtr);
+ void UnsetNotifier(USER_PTR userPtr);
+
+private:
+ SMUX(const SMUX & rvalue);
+ SMUX & operator=(const SMUX & rvalue);
+
+ static void * Runner(void * d);
+ void Run();
+ bool PrepareNet();
+
+ bool DispatchPDUs(const SMUX_PDUs_t * pdus);
+
+ bool CloseHandler(const SMUX_PDUs_t * pdus);
+ bool RegisterResponseHandler(const SMUX_PDUs_t * pdus);
+ bool PDUsRequestHandler(const SMUX_PDUs_t * pdus);
+ bool CommitOrRollbackHandler(const SMUX_PDUs_t * pdus);
+
+ bool GetRequestHandler(const PDUs_t * pdus);
+ bool GetNextRequestHandler(const PDUs_t * pdus);
+ bool SetRequestHandler(const PDUs_t * pdus);
+
+ void SetNotifiers();
+ void ResetNotifiers();
+
+ USERS * users;
+ TARIFFS * tariffs;
+ ADMINS * admins;
+ SERVICES * services;
+ CORPORATIONS * corporations;
+ TRAFFCOUNTER * traffcounter;
+
+ mutable std::string errorStr;
+ SMUX_SETTINGS smuxSettings;
+ MODULE_SETTINGS settings;
+
+ pthread_t thread;
+ pthread_mutex_t mutex;
+ bool running;
+ bool stopped;
+
+ int sock;
+
+ SMUXHandlers smuxHandlers;
+ PDUsHandlers pdusHandlers;
+ Sensors sensors;
+ Tables tables;
+
+ std::list<CHG_AFTER_NOTIFIER> notifiers;
+ ADD_USER_NOTIFIER addUserNotifier;
+ DEL_USER_NOTIFIER delUserNotifier;
+ ADD_DEL_TARIFF_NOTIFIER addDelTariffNotifier;
+};
+//-----------------------------------------------------------------------------
+
+inline
+void ADD_DEL_TARIFF_NOTIFIER::Notify(const TARIFF_DATA &)
+{
+smux.UpdateTables();
+}
+
+inline
+void ADD_USER_NOTIFIER::Notify(const USER_PTR & userPtr)
+{
+smux.SetNotifier(userPtr);
+smux.UpdateTables();
+}
+
+inline
+void DEL_USER_NOTIFIER::Notify(const USER_PTR & userPtr)
+{
+smux.UnsetNotifier(userPtr);
+smux.UpdateTables();
+}
+
+extern "C" PLUGIN * GetPlugin();
+
+#endif
--- /dev/null
+#include <cassert>
+#include <utility>
+#include <iterator>
+#include <algorithm>
+
+#include "stg/user_property.h"
+#include "stg/tariffs.h"
+#include "stg/users.h"
+
+#include "tables.h"
+
+std::pair<std::string, size_t> TD2Info(const TARIFF_DATA & td);
+
+void TariffUsersTable::UpdateSensors(Sensors & sensors) const
+{
+std::map<std::string, size_t> data;
+
+std::list<TARIFF_DATA> tdl;
+tariffs.GetTariffsData(&tdl);
+std::transform(tdl.begin(),
+ tdl.end(),
+ std::inserter(data, data.begin()),
+ TD2Info);
+
+int handle = users.OpenSearch();
+assert(handle && "USERS::OpenSearch is always correct");
+
+USER_PTR user;
+while (!users.SearchNext(handle, &user))
+ {
+ if (user->GetDeleted())
+ continue;
+ std::string tariffName(user->GetProperty().tariffName.ConstData());
+ std::map<std::string, size_t>::iterator it;
+ it = data.lower_bound(tariffName);
+ if (it == data.end() ||
+ it->first != tariffName)
+ {
+ data.insert(it, std::make_pair(tariffName, 1));
+ }
+ else
+ {
+ ++it->second;
+ }
+ }
+
+users.CloseSearch(handle);
+
+size_t idx = 1;
+OID prefixOid(prefix);
+
+std::map<std::string, size_t>::const_iterator it(data.begin());
+while (it != data.end())
+ {
+ sensors[prefixOid.copyWithSuffix(2, idx)] = new ConstSensor<std::string>(it->first);
+ sensors[prefixOid.copyWithSuffix(3, idx)] = new ConstSensor<int>(it->second);
+ ++idx;
+ ++it;
+ }
+}
+
+std::pair<std::string, size_t> TD2Info(const TARIFF_DATA & td)
+{
+return std::make_pair(td.tariffConf.name, 0);
+}
--- /dev/null
+#ifndef __TABLES_H__
+#define __TABLES_H__
+
+#include <string>
+#include <map>
+
+#include "sensors.h"
+
+class TARIFFS;
+class USERS;
+
+class TableSensor {
+ public:
+ TableSensor(const std::string & p) : prefix(p) {}
+ virtual ~TableSensor() {}
+
+ const std::string & GetPrefix() const { return prefix; }
+ virtual void UpdateSensors(Sensors & sensors) const = 0;
+
+ protected:
+ std::string prefix;
+};
+
+class TariffUsersTable : public TableSensor {
+ public:
+ TariffUsersTable(const std::string & p,
+ TARIFFS & t,
+ USERS & u)
+ : TableSensor(p),
+ tariffs(t),
+ users(u)
+ {}
+ virtual ~TariffUsersTable() {}
+
+ void UpdateSensors(Sensors & sensors) const;
+
+ private:
+ TARIFFS & tariffs;
+ USERS & users;
+};
+
+typedef std::map<std::string, TableSensor *> Tables;
+
+#endif
--- /dev/null
+#include <stdexcept>
+#include <algorithm>
+#include <iterator>
+#include <sstream>
+
+#include "types.h"
+
+bool ParseArcs(const char * str, ptrdiff_t length, unsigned * a, size_t * pos)
+{
+if (length == 0)
+ return false;
+const char * left = str;
+if (*left == '.')
+ ++left;
+size_t arcPos = 0;
+while ((left - str) < length)
+ {
+ char * pos = NULL;
+ unsigned arc = strtoul(left, &pos, 10);
+ if (pos == left)
+ return false;
+ a[arcPos++] = arc;
+ if (arcPos >= 1024)
+ return false;
+ left = pos + 1;
+ }
+*pos = arcPos;
+return true;
+}
+
+bool StringToArcs(const char * str, size_t length, std::vector<unsigned> & arcs)
+{
+unsigned a[1024];
+size_t pos = 0;
+
+if (!ParseArcs(str, length, a, &pos))
+ return false;
+
+arcs.assign(a, a + pos);
+return true;
+}
+
+bool AppendToArcs(const char * str, size_t length, std::vector<unsigned> & arcs)
+{
+unsigned a[1024];
+size_t pos = 0;
+
+if (!ParseArcs(str, length, a, &pos))
+ return false;
+
+std::copy(&a[0], &a[pos], std::back_inserter(arcs));
+return true;
+}
+
+OID::OID(const std::string & str)
+ : arcs()
+{
+if (!StringToArcs(str.c_str(), str.length(), arcs))
+ throw std::runtime_error("Invalid oid");
+}
+
+OID::OID(const char * str, size_t length)
+ : arcs()
+{
+if (!StringToArcs(str, length, arcs))
+ throw std::runtime_error("Invalid oid");
+}
+
+OID::OID(const std::vector<unsigned> & a)
+ : arcs(a)
+{
+}
+
+OID::OID(const unsigned * a, size_t length)
+ : arcs()
+{
+std::vector<unsigned> newArcs(a, a + length);
+arcs.swap(newArcs);
+}
+
+OID::OID(OBJECT_IDENTIFIER_t * oid)
+ : arcs()
+{
+unsigned a[1024];
+int count = OBJECT_IDENTIFIER_get_arcs(oid, a, sizeof(a[0]), 1024);
+
+if (count > 1024)
+ throw std::runtime_error("OID is too long");
+
+std::vector<unsigned> newArcs(a, a + count);
+arcs.swap(newArcs);
+}
+
+OID::OID(const OID & rvalue)
+ : arcs(rvalue.arcs)
+{
+}
+
+OID::~OID()
+{
+}
+
+bool OID::addSuffix(const char * suffix, size_t length)
+{
+if (!AppendToArcs(suffix, length, arcs))
+ return false;
+return true;
+}
+
+bool OID::addSuffix(const std::string & suffix)
+{
+if (!AppendToArcs(suffix.c_str(), suffix.length(), arcs))
+ return false;
+return true;
+}
+
+bool OID::addSuffix(const unsigned * suffix, size_t length)
+{
+std::copy(suffix, suffix + length, std::back_inserter(arcs));
+return true;
+}
+
+bool OID::addSuffix(const std::vector<unsigned> & suffix)
+{
+std::copy(suffix.begin(), suffix.end(), std::back_inserter(arcs));
+return true;
+}
+
+bool OID::addSuffix(unsigned a, unsigned b)
+{
+arcs.push_back(a);
+arcs.push_back(b);
+return true;
+}
+
+OID OID::copyWithSuffix(const char * suffix, size_t length) const
+{
+OID oid(*this);
+if (!oid.addSuffix(suffix, length))
+ throw std::runtime_error("Invalid suffix");
+return oid;
+}
+
+OID OID::copyWithSuffix(const std::string & suffix) const
+{
+OID oid(*this);
+if (!oid.addSuffix(suffix))
+ throw std::runtime_error("Invalid suffix");
+return oid;
+}
+
+OID OID::copyWithSuffix(const unsigned * suffix, size_t length) const
+{
+OID oid(*this);
+if (!oid.addSuffix(suffix, length))
+ throw std::runtime_error("Invalid suffix");
+return oid;
+}
+
+OID OID::copyWithSuffix(const std::vector<unsigned> & suffix) const
+{
+OID oid(*this);
+if (!oid.addSuffix(suffix))
+ throw std::runtime_error("Invalid suffix");
+return oid;
+}
+
+OID OID::copyWithSuffix(unsigned a, unsigned b) const
+{
+OID oid(*this);
+oid.addSuffix(a, b);
+return oid;
+}
+
+std::string OID::ToString() const
+{
+std::stringstream stream;
+for (size_t i = 0; i < arcs.size(); ++i)
+ stream << "." << arcs[i];
+return stream.str();
+}
+
+void OID::ToOID(OBJECT_IDENTIFIER_t * oid) const
+{
+OBJECT_IDENTIFIER_set_arcs(oid, &arcs.front(), sizeof(unsigned), arcs.size());
+}
+
+OID & OID::operator=(const OID & rvalue)
+{
+arcs = rvalue.arcs;
+return *this;
+}
+
+bool OID::operator==(const OID & rvalue) const
+{
+if (arcs.size() != rvalue.arcs.size())
+ return false;
+for (size_t i = 0; i < arcs.size(); ++i)
+ if (arcs[i] != rvalue.arcs[i])
+ return false;
+return true;
+}
+
+bool OID::operator<(const OID & rvalue) const
+{
+size_t i = 0;
+size_t min = std::min(arcs.size(), rvalue.arcs.size());
+while (i < min &&
+ arcs[i] == rvalue.arcs[i])
+ ++i;
+if (i == min)
+ {
+ if (rvalue.arcs.size() > arcs.size())
+ return true;
+ return false;
+ }
+
+if (arcs[i] < rvalue.arcs[i])
+ return true;
+
+return false;
+}
+
+bool OID::PrefixLess(const OID & rvalue) const
+{
+size_t i = 0;
+size_t min = std::min(arcs.size(), rvalue.arcs.size());
+while (i < min &&
+ arcs[i] == rvalue.arcs[i])
+ ++i;
+if (i == min)
+ return false;
+if (arcs[i] < rvalue.arcs[i])
+ return true;
+return false;
+}
+
+std::ostream & operator<<(std::ostream & stream, const OID & oid)
+{
+for (size_t i = 0; i < oid.arcs.size(); ++i)
+ stream << "." << oid.arcs[i];
+return stream;
+}
--- /dev/null
+#ifndef __TYPES_H__
+#define __TYPES_H__
+
+#include <string>
+#include <vector>
+#include <iostream>
+
+#include "stg/OBJECT_IDENTIFIER.h"
+
+class OID {
+ public:
+ OID(const std::string & str);
+ OID(const char * str, size_t length);
+ OID(const std::vector<unsigned> & arcs);
+ OID(const unsigned * arcs, size_t length);
+ OID(OBJECT_IDENTIFIER_t * oid);
+ OID(const OID & rvalue);
+ ~OID();
+
+ bool addSuffix(const char * suffix, size_t length);
+ bool addSuffix(const std::string & suffix);
+ bool addSuffix(const unsigned * suffix, size_t length);
+ bool addSuffix(const std::vector<unsigned> & suffix);
+ bool addSuffix(unsigned a, unsigned b);
+
+ OID copyWithSuffix(const char * suffix, size_t length) const;
+ OID copyWithSuffix(const std::string & suffix) const;
+ OID copyWithSuffix(const unsigned * suffix, size_t length) const;
+ OID copyWithSuffix(const std::vector<unsigned> & suffix) const;
+ OID copyWithSuffix(unsigned a, unsigned b) const;
+
+ std::string ToString() const;
+ const std::vector<unsigned> & ToVector() const { return arcs; }
+ void ToOID(OBJECT_IDENTIFIER_t * oid) const;
+
+ OID & operator=(const OID & rvalue);
+ bool operator==(const OID & rvalue) const;
+ bool operator!=(const OID & rvalue) const { return !operator==(rvalue); }
+ bool operator<(const OID & rvalue) const;
+ bool operator>(const OID & rvalue) const
+ { return !operator==(rvalue) && !operator<(rvalue); }
+
+ bool PrefixLess(const OID & rvalue) const;
+
+ friend std::ostream & operator<<(std::ostream & stream, const OID & oid);
+
+ private:
+ std::vector<unsigned> arcs;
+};
+
+inline
+bool PrefixLess(const OID & a, const OID & b)
+{
+return a.PrefixLess(b);
+}
+
+#endif
--- /dev/null
+#include <unistd.h> // write
+
+#include <cstring> // memset
+#include <cerrno>
+
+#include "stg/common.h"
+
+#include "stg/OpenPDU.h"
+#include "stg/ClosePDU.h"
+#include "stg/RReqPDU.h"
+#include "stg/ber_decoder.h"
+#include "stg/der_encoder.h"
+
+#include "pen.h"
+#include "utils.h"
+
+bool String2OI(const std::string & str, OBJECT_IDENTIFIER_t * oi)
+{
+size_t left = 0, pos = 0, arcPos = 0;
+int arcs[1024];
+pos = str.find_first_of('.', left);
+if (pos == 0)
+ {
+ left = 1;
+ pos = str.find_first_of('.', left);
+ }
+while (pos != std::string::npos)
+ {
+ int arc = 0;
+ if (str2x(str.substr(left, left - pos), arc))
+ {
+ return false;
+ }
+ arcs[arcPos++] = arc;
+ left = pos + 1;
+ pos = str.find_first_of('.', left);
+ }
+if (left < str.length())
+ {
+ int arc = 0;
+ if (str2x(str.substr(left, left - pos), arc))
+ {
+ return false;
+ }
+ arcs[arcPos++] = arc;
+ }
+OBJECT_IDENTIFIER_set_arcs(oi, arcs, sizeof(arcs[0]), arcPos);
+return true;
+}
+
+std::string OI2String(OBJECT_IDENTIFIER_t * oi)
+{
+std::string res;
+
+int arcs[1024];
+int count = OBJECT_IDENTIFIER_get_arcs(oi, arcs, sizeof(arcs[0]), 1024);
+
+if (count > 1024)
+ return "";
+
+for (int i = 0; i < count; ++i)
+ {
+ res += ".";
+ std::string arc;
+ strprintf(&arc, "%d", arcs[i]);
+ res += arc;
+ }
+
+return res;
+}
+
+bool SendOpenPDU(int fd)
+{
+const char * description = "Stg SMUX Plugin";
+asn_enc_rval_t error;
+OpenPDU_t msg;
+
+memset(&msg, 0, sizeof(msg));
+
+msg.present = OpenPDU_PR_simple;
+asn_long2INTEGER(&msg.choice.simple.version, SimpleOpen__version_version_1);
+if (!String2OI(PEN_PREFIX, &msg.choice.simple.identity))
+ {
+ printfd(__FILE__,
+ "SendOpenPDU() - failed to convert string to OBJECT_IDENTIFIER\n");
+ return false;
+ }
+OCTET_STRING_fromString(&msg.choice.simple.description, description);
+OCTET_STRING_fromString(&msg.choice.simple.password, "");
+
+char buffer[1024];
+error = der_encode_to_buffer(&asn_DEF_OpenPDU, &msg, buffer, sizeof(buffer));
+
+ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_OpenPDU, &msg);
+
+if (error.encoded == -1)
+ {
+ printfd(__FILE__, "Could not encode OpenPDU (at %s)\n",
+ error.failed_type ? error.failed_type->name : "unknown");
+ return false;
+ }
+else
+ {
+ if (write(fd, buffer, error.encoded) < 0)
+ {
+ printfd(__FILE__, "Failed to send OpenPDU: %s\n", strerror(errno));
+ return false;
+ }
+ }
+return true;
+}
+
+bool SendClosePDU(int fd)
+{
+ClosePDU_t msg;
+
+memset(&msg, 0, sizeof(msg));
+
+asn_long2INTEGER(&msg, ClosePDU_goingDown);
+
+char buffer[1024];
+asn_enc_rval_t error;
+error = der_encode_to_buffer(&asn_DEF_ClosePDU, &msg, buffer, sizeof(buffer));
+
+ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_ClosePDU, &msg);
+
+if (error.encoded == -1)
+ {
+ printfd(__FILE__, "Could not encode ClosePDU (at %s)\n",
+ error.failed_type ? error.failed_type->name : "unknown");
+ return false;
+ }
+else
+ {
+ if (write(fd, buffer, error.encoded) < 0)
+ {
+ printfd(__FILE__, "Failed to send ClosePDU: %s\n", strerror(errno));
+ return false;
+ }
+ }
+return true;
+}
+
+bool SendRReqPDU(int fd)
+{
+int oid[] = {1, 3, 6, 1, 4, 1, 38313, 1};
+asn_enc_rval_t error;
+RReqPDU_t msg;
+
+memset(&msg, 0, sizeof(msg));
+
+msg.priority = 0;
+asn_long2INTEGER(&msg.operation, RReqPDU__operation_readOnly);
+OBJECT_IDENTIFIER_set_arcs(&msg.subtree,
+ oid,
+ sizeof(oid[0]),
+ 8);
+
+char buffer[1024];
+error = der_encode_to_buffer(&asn_DEF_RReqPDU, &msg, buffer, sizeof(buffer));
+
+ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_RReqPDU, &msg);
+
+if (error.encoded == -1)
+ {
+ printfd(__FILE__, "Could not encode RReqPDU (at %s)\n",
+ error.failed_type ? error.failed_type->name : "unknown");
+ return false;
+ }
+else
+ {
+ if (write(fd, buffer, error.encoded) < 0)
+ {
+ printfd(__FILE__, "Failed to send RReqPDU: %s\n", strerror(errno));
+ return false;
+ }
+ }
+return true;
+}
+
+SMUX_PDUs_t * RecvSMUXPDUs(int fd)
+{
+char buffer[1024];
+SMUX_PDUs_t * pdus = NULL;
+
+memset(buffer, 0, sizeof(buffer));
+
+size_t length = read(fd, buffer, sizeof(buffer));
+if (length < 1)
+ return NULL;
+asn_dec_rval_t error;
+error = ber_decode(0, &asn_DEF_SMUX_PDUs, (void **)&pdus, buffer, length);
+
+if(error.code != RC_OK)
+ {
+ printfd(__FILE__, "Failed to decode PDUs at byte %ld\n",
+ (long)error.consumed);
+ return NULL;
+ }
+return pdus;
+}
+
+bool SendGetResponsePDU(int fd, GetResponse_PDU_t * getResponse)
+{
+asn_enc_rval_t error;
+
+char buffer[1024];
+error = der_encode_to_buffer(&asn_DEF_GetResponse_PDU, getResponse, buffer,
+ sizeof(buffer));
+
+if (error.encoded == -1)
+ {
+ printfd(__FILE__, "Could not encode GetResponsePDU (at %s)\n",
+ error.failed_type ? error.failed_type->name : "unknown");
+ return false;
+ }
+else
+ {
+ if (write(fd, buffer, error.encoded) < 0)
+ {
+ printfd(__FILE__, "Failed to send GetResponsePDU: %s\n", strerror(errno));
+ return false;
+ }
+ }
+return true;
+}
+
+bool SendGetResponseErrorPDU(int fd,
+ const PDU_t * getRequest,
+ int errorStatus,
+ int errorIndex)
+{
+asn_enc_rval_t error;
+GetResponse_PDU_t msg;
+
+memset(&msg, 0, sizeof(msg));
+
+long id = 0;
+asn_INTEGER2long(&getRequest->request_id, &id);
+asn_long2INTEGER(&msg.request_id, id);
+asn_long2INTEGER(&msg.error_status, errorStatus);
+asn_long2INTEGER(&msg.error_index, errorIndex);
+
+char buffer[1024];
+error = der_encode_to_buffer(&asn_DEF_GetResponse_PDU, &msg, buffer,
+ sizeof(buffer));
+
+ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_GetResponse_PDU, &msg);
+
+if (error.encoded == -1)
+ {
+ printfd(__FILE__, "Could not encode GetResponsePDU for error (at %s)\n",
+ error.failed_type ? error.failed_type->name : "unknown");
+ return false;
+ }
+else
+ {
+ if (write(fd, buffer, error.encoded) < 0)
+ {
+ printfd(__FILE__, "Failed to send GetResponseErrorPDU: %s\n", strerror(errno));
+ return false;
+ }
+ }
+return true;
+}
--- /dev/null
+#ifndef __UTILS_H__
+#define __UTILS_H__
+
+#include <string>
+
+#include "stg/OBJECT_IDENTIFIER.h"
+#include "stg/SMUX-PDUs.h"
+#include "stg/GetResponse-PDU.h"
+
+bool String2OI(const std::string & str, OBJECT_IDENTIFIER_t * oi);
+std::string OI2String(OBJECT_IDENTIFIER_t * oi);
+bool SendOpenPDU(int fd);
+bool SendClosePDU(int fd);
+bool SendRReqPDU(int fd);
+SMUX_PDUs_t * RecvSMUXPDUs(int fd);
+bool SendGetResponsePDU(int fd, GetResponse_PDU_t * getResponse);
+bool SendGetResponseErrorPDU(int fd,
+ const PDU_t * getRequest,
+ int errorStatus,
+ int errorIndex);
+
+#endif
--- /dev/null
+#ifndef __VALUE_2_OS_H__
+#define __VALUE_2_OS_H__
+
+#include "stg/ObjectSyntax.h"
+
+template <typename T>
+bool ValueToOS(const T & value, ObjectSyntax * objectSyntax);
+
+template <>
+inline
+bool ValueToOS<int>(const int & value, ObjectSyntax * objectSyntax)
+{
+objectSyntax->present = ObjectSyntax_PR_simple;
+SimpleSyntax_t * simpleSyntax = &objectSyntax->choice.simple;
+simpleSyntax->present = SimpleSyntax_PR_number;
+asn_long2INTEGER(&simpleSyntax->choice.number, value);
+return true;
+}
+
+template <>
+inline
+bool ValueToOS<unsigned int>(const unsigned int & value, ObjectSyntax * objectSyntax)
+{
+objectSyntax->present = ObjectSyntax_PR_simple;
+SimpleSyntax_t * simpleSyntax = &objectSyntax->choice.simple;
+simpleSyntax->present = SimpleSyntax_PR_number;
+asn_long2INTEGER(&simpleSyntax->choice.number, value);
+return true;
+}
+
+template <>
+inline
+bool ValueToOS<long>(const long & value, ObjectSyntax * objectSyntax)
+{
+objectSyntax->present = ObjectSyntax_PR_simple;
+SimpleSyntax_t * simpleSyntax = &objectSyntax->choice.simple;
+simpleSyntax->present = SimpleSyntax_PR_number;
+asn_long2INTEGER(&simpleSyntax->choice.number, value);
+return true;
+}
+
+template <>
+inline
+bool ValueToOS<unsigned long>(const unsigned long & value, ObjectSyntax * objectSyntax)
+{
+objectSyntax->present = ObjectSyntax_PR_simple;
+SimpleSyntax_t * simpleSyntax = &objectSyntax->choice.simple;
+simpleSyntax->present = SimpleSyntax_PR_number;
+asn_long2INTEGER(&simpleSyntax->choice.number, value);
+return true;
+}
+
+template <>
+inline
+bool ValueToOS<std::string>(const std::string & value, ObjectSyntax * objectSyntax)
+{
+objectSyntax->present = ObjectSyntax_PR_simple;
+SimpleSyntax_t * simpleSyntax = &objectSyntax->choice.simple;
+simpleSyntax->present = SimpleSyntax_PR_string;
+OCTET_STRING_fromBuf(&simpleSyntax->choice.string, value.c_str(), value.length());
+return true;
+}
+
+#endif
+++ /dev/null
-###############################################################################
-# $Id: Makefile,v 1.11 2008/12/04 17:21:14 faust Exp $
-###############################################################################
-
-include ../../../../../Makefile.conf
-
-LIBS += $(LIB_THREAD)
-
-PROG = mod_snmp_agent.so
-
-SRCS = snmp.cpp \
- sensors.cpp \
- asn1/DisplayString.c \
- asn1/PhysAddress.c \
- asn1/IfEntry.c \
- asn1/AtEntry.c \
- asn1/IpAddrEntry.c \
- asn1/IpRouteEntry.c \
- asn1/IpNetToMediaEntry.c \
- asn1/TcpConnEntry.c \
- asn1/UdpEntry.c \
- asn1/EgpNeighEntry.c \
- asn1/ObjectName.c \
- asn1/ObjectSyntax.c \
- asn1/SimpleSyntax.c \
- asn1/ApplicationSyntax.c \
- asn1/NetworkAddress.c \
- asn1/IpAddress.c \
- asn1/Counter.c \
- asn1/Gauge.c \
- asn1/TimeTicks.c \
- asn1/Opaque.c \
- asn1/Message.c \
- asn1/PDUs.c \
- asn1/GetRequest-PDU.c \
- asn1/GetNextRequest-PDU.c \
- asn1/GetResponse-PDU.c \
- asn1/SetRequest-PDU.c \
- asn1/PDU.c \
- asn1/Trap-PDU.c \
- asn1/VarBind.c \
- asn1/VarBindList.c \
- asn1/SMUX-PDUs.c \
- asn1/OpenPDU.c \
- asn1/SimpleOpen.c \
- asn1/ClosePDU.c \
- asn1/RReqPDU.c \
- asn1/RRspPDU.c \
- asn1/SOutPDU.c \
- asn1/ANY.c \
- asn1/BOOLEAN.c \
- asn1/INTEGER.c \
- asn1/NULL.c \
- asn1/NativeEnumerated.c \
- asn1/NativeInteger.c \
- asn1/OBJECT_IDENTIFIER.c \
- asn1/asn_SEQUENCE_OF.c \
- asn1/asn_SET_OF.c \
- asn1/constr_CHOICE.c \
- asn1/constr_SEQUENCE.c \
- asn1/constr_SEQUENCE_OF.c \
- asn1/constr_SET_OF.c \
- asn1/OCTET_STRING.c \
- asn1/BIT_STRING.c \
- asn1/asn_codecs_prim.c \
- asn1/ber_tlv_length.c \
- asn1/ber_tlv_tag.c \
- asn1/ber_decoder.c \
- asn1/der_encoder.c \
- asn1/constr_TYPE.c \
- asn1/constraints.c \
- asn1/xer_support.c \
- asn1/xer_decoder.c \
- asn1/xer_encoder.c \
- asn1/per_support.c \
- asn1/per_decoder.c \
- asn1/per_encoder.c
-
-STGLIBS = -lstgcommon
-
-CXXFLAGS += -Iasn1
-
-include ../../Makefile.in
-
-.PHONY: asn1
-
-asn1:
- $(MAKE) -C asn1 asn1
+++ /dev/null
-Количество пользователей всего в биллинге
-Количество пользователей онлайн
-Количество пользователей с отрицательный балансом
-Количество пользователей с всегда онлайн
-Количество пользователей по отношению к каждому из тарифов
-Количество пользователей по отношению к каждому UserData полю - ?
-Количество пользователей с отключенной детальной статистикой
-Количество отключенных пользователей
-Количество замороженных пользователей
-Количество пользователей, у которых есть кредит
-Количество пользователей, у которых есть предоплаченный трафик
-
-Количество тарифов
-Количество направлений
+++ /dev/null
-/*-
- * Copyright (c) 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-#include <asn_internal.h>
-#include <ANY.h>
-#include <errno.h>
-
-static asn_OCTET_STRING_specifics_t asn_DEF_ANY_specs = {
- sizeof(ANY_t),
- offsetof(ANY_t, _asn_ctx),
- 2 /* Special indicator that this is an ANY type */
-};
-asn_TYPE_descriptor_t asn_DEF_ANY = {
- "ANY",
- "ANY",
- OCTET_STRING_free,
- OCTET_STRING_print,
- asn_generic_no_constraint,
- OCTET_STRING_decode_ber,
- OCTET_STRING_encode_der,
- OCTET_STRING_decode_xer_hex,
- ANY_encode_xer,
- 0, 0,
- 0, /* Use generic outmost tag fetcher */
- 0, 0, 0, 0,
- 0, /* No PER visible constraints */
- 0, 0, /* No members */
- &asn_DEF_ANY_specs,
-};
-
-
-asn_enc_rval_t
-ANY_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
- int ilevel, enum xer_encoder_flags_e flags,
- asn_app_consume_bytes_f *cb, void *app_key) {
-
- if(flags & XER_F_CANONICAL) {
- /*
- * Canonical XER-encoding of ANY type is not supported.
- */
- _ASN_ENCODE_FAILED;
- }
-
- /* Dump as binary */
- return OCTET_STRING_encode_xer(td, sptr, ilevel, flags, cb, app_key);
-}
-
-struct _callback_arg {
- uint8_t *buffer;
- size_t offset;
- size_t size;
-};
-
-static int ANY__consume_bytes(const void *buffer, size_t size, void *key);
-
-int
-ANY_fromType(ANY_t *st, asn_TYPE_descriptor_t *td, void *sptr) {
- struct _callback_arg arg;
- asn_enc_rval_t erval;
-
- if(!st || !td) {
- errno = EINVAL;
- return -1;
- }
-
- if(!sptr) {
- if(st->buf) FREEMEM(st->buf);
- st->size = 0;
- return 0;
- }
-
- arg.offset = arg.size = 0;
- arg.buffer = 0;
-
- erval = der_encode(td, sptr, ANY__consume_bytes, &arg);
- if(erval.encoded == -1) {
- if(arg.buffer) FREEMEM(arg.buffer);
- return -1;
- }
- assert((size_t)erval.encoded == arg.offset);
-
- if(st->buf) FREEMEM(st->buf);
- st->buf = arg.buffer;
- st->size = arg.offset;
-
- return 0;
-}
-
-ANY_t *
-ANY_new_fromType(asn_TYPE_descriptor_t *td, void *sptr) {
- ANY_t tmp;
- ANY_t *st;
-
- if(!td || !sptr) {
- errno = EINVAL;
- return 0;
- }
-
- memset(&tmp, 0, sizeof(tmp));
-
- if(ANY_fromType(&tmp, td, sptr)) return 0;
-
- st = (ANY_t *)CALLOC(1, sizeof(ANY_t));
- if(st) {
- *st = tmp;
- return st;
- } else {
- FREEMEM(tmp.buf);
- return 0;
- }
-}
-
-int
-ANY_to_type(ANY_t *st, asn_TYPE_descriptor_t *td, void **struct_ptr) {
- asn_dec_rval_t rval;
- void *newst = 0;
-
- if(!st || !td || !struct_ptr) {
- errno = EINVAL;
- return -1;
- }
-
- if(st->buf == 0) {
- /* Nothing to convert, make it empty. */
- *struct_ptr = (void *)0;
- return 0;
- }
-
- rval = ber_decode(0, td, (void **)&newst, st->buf, st->size);
- if(rval.code == RC_OK) {
- *struct_ptr = newst;
- return 0;
- } else {
- /* Remove possibly partially decoded data. */
- ASN_STRUCT_FREE(*td, newst);
- return -1;
- }
-}
-
-static int ANY__consume_bytes(const void *buffer, size_t size, void *key) {
- struct _callback_arg *arg = (struct _callback_arg *)key;
-
- if((arg->offset + size) >= arg->size) {
- size_t nsize = (arg->size ? arg->size << 2 : 16) + size;
- void *p = REALLOC(arg->buffer, nsize);
- if(!p) return -1;
- arg->buffer = (uint8_t *)p;
- arg->size = nsize;
- }
-
- memcpy(arg->buffer + arg->offset, buffer, size);
- arg->offset += size;
- assert(arg->offset < arg->size);
-
- return 0;
-}
-
+++ /dev/null
-/*-
- * Copyright (c) 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-#ifndef ASN_TYPE_ANY_H
-#define ASN_TYPE_ANY_H
-
-#include <OCTET_STRING.h> /* Implemented via OCTET STRING type */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct ANY {
- uint8_t *buf; /* BER-encoded ANY contents */
- int size; /* Size of the above buffer */
-
- asn_struct_ctx_t _asn_ctx; /* Parsing across buffer boundaries */
-} ANY_t;
-
-extern asn_TYPE_descriptor_t asn_DEF_ANY;
-
-asn_struct_free_f ANY_free;
-asn_struct_print_f ANY_print;
-ber_type_decoder_f ANY_decode_ber;
-der_type_encoder_f ANY_encode_der;
-xer_type_encoder_f ANY_encode_xer;
-
-/******************************
- * Handy conversion routines. *
- ******************************/
-
-/* Convert another ASN.1 type into the ANY. This implies DER encoding. */
-int ANY_fromType(ANY_t *, asn_TYPE_descriptor_t *td, void *struct_ptr);
-ANY_t *ANY_new_fromType(asn_TYPE_descriptor_t *td, void *struct_ptr);
-
-/* Convert the contents of the ANY type into the specified type. */
-int ANY_to_type(ANY_t *, asn_TYPE_descriptor_t *td, void **struct_ptr);
-
-#define ANY_fromBuf(s, buf, size) OCTET_STRING_fromBuf((s), (buf), (size))
-#define ANY_new_fromBuf(buf, size) OCTET_STRING_new_fromBuf( \
- &asn_DEF_ANY, (buf), (size))
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* ASN_TYPE_ANY_H */
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1155-SMI"
- * found in "RFC1155-SMI.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#include <asn_internal.h>
-
-#include "ApplicationSyntax.h"
-
-static asn_TYPE_member_t asn_MBR_ApplicationSyntax_1[] = {
- { ATF_NOFLAGS, 0, offsetof(struct ApplicationSyntax, choice.address),
- -1 /* Ambiguous tag (CHOICE?) */,
- 0,
- &asn_DEF_NetworkAddress,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "address"
- },
- { ATF_NOFLAGS, 0, offsetof(struct ApplicationSyntax, choice.counter),
- (ASN_TAG_CLASS_APPLICATION | (1 << 2)),
- 0,
- &asn_DEF_Counter,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "counter"
- },
- { ATF_NOFLAGS, 0, offsetof(struct ApplicationSyntax, choice.gauge),
- (ASN_TAG_CLASS_APPLICATION | (2 << 2)),
- 0,
- &asn_DEF_Gauge,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "gauge"
- },
- { ATF_NOFLAGS, 0, offsetof(struct ApplicationSyntax, choice.ticks),
- (ASN_TAG_CLASS_APPLICATION | (3 << 2)),
- 0,
- &asn_DEF_TimeTicks,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "ticks"
- },
- { ATF_NOFLAGS, 0, offsetof(struct ApplicationSyntax, choice.arbitrary),
- (ASN_TAG_CLASS_APPLICATION | (4 << 2)),
- 0,
- &asn_DEF_Opaque,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "arbitrary"
- },
-};
-static asn_TYPE_tag2member_t asn_MAP_ApplicationSyntax_tag2el_1[] = {
- { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 0, 0, 0 }, /* internet at 113 */
- { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 1, 0, 0 }, /* counter at 91 */
- { (ASN_TAG_CLASS_APPLICATION | (2 << 2)), 2, 0, 0 }, /* gauge at 94 */
- { (ASN_TAG_CLASS_APPLICATION | (3 << 2)), 3, 0, 0 }, /* ticks at 97 */
- { (ASN_TAG_CLASS_APPLICATION | (4 << 2)), 4, 0, 0 } /* arbitrary at 104 */
-};
-static asn_CHOICE_specifics_t asn_SPC_ApplicationSyntax_specs_1 = {
- sizeof(struct ApplicationSyntax),
- offsetof(struct ApplicationSyntax, _asn_ctx),
- offsetof(struct ApplicationSyntax, present),
- sizeof(((struct ApplicationSyntax *)0)->present),
- asn_MAP_ApplicationSyntax_tag2el_1,
- 5, /* Count of tags in the map */
- 0,
- -1 /* Extensions start */
-};
-asn_TYPE_descriptor_t asn_DEF_ApplicationSyntax = {
- "ApplicationSyntax",
- "ApplicationSyntax",
- CHOICE_free,
- CHOICE_print,
- CHOICE_constraint,
- CHOICE_decode_ber,
- CHOICE_encode_der,
- CHOICE_decode_xer,
- CHOICE_encode_xer,
- 0, 0, /* No PER support, use "-gen-PER" to enable */
- CHOICE_outmost_tag,
- 0, /* No effective tags (pointer) */
- 0, /* No effective tags (count) */
- 0, /* No tags (pointer) */
- 0, /* No tags (count) */
- 0, /* No PER visible constraints */
- asn_MBR_ApplicationSyntax_1,
- 5, /* Elements count */
- &asn_SPC_ApplicationSyntax_specs_1 /* Additional specs */
-};
-
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1155-SMI"
- * found in "RFC1155-SMI.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#ifndef _ApplicationSyntax_H_
-#define _ApplicationSyntax_H_
-
-
-#include <asn_application.h>
-
-/* Including external dependencies */
-#include "NetworkAddress.h"
-#include "Counter.h"
-#include "Gauge.h"
-#include "TimeTicks.h"
-#include "Opaque.h"
-#include <constr_CHOICE.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Dependencies */
-typedef enum ApplicationSyntax_PR {
- ApplicationSyntax_PR_NOTHING, /* No components present */
- ApplicationSyntax_PR_address,
- ApplicationSyntax_PR_counter,
- ApplicationSyntax_PR_gauge,
- ApplicationSyntax_PR_ticks,
- ApplicationSyntax_PR_arbitrary
-} ApplicationSyntax_PR;
-
-/* ApplicationSyntax */
-typedef struct ApplicationSyntax {
- ApplicationSyntax_PR present;
- union ApplicationSyntax_u {
- NetworkAddress_t address;
- Counter_t counter;
- Gauge_t gauge;
- TimeTicks_t ticks;
- Opaque_t arbitrary;
- } choice;
-
- /* Context for parsing across buffer boundaries */
- asn_struct_ctx_t _asn_ctx;
-} ApplicationSyntax_t;
-
-/* Implementation */
-extern asn_TYPE_descriptor_t asn_DEF_ApplicationSyntax;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _ApplicationSyntax_H_ */
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1213-MIB"
- * found in "RFC1213-MIB.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#include <asn_internal.h>
-
-#include "AtEntry.h"
-
-static asn_TYPE_member_t asn_MBR_AtEntry_1[] = {
- { ATF_NOFLAGS, 0, offsetof(struct AtEntry, atIfIndex),
- (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
- 0,
- &asn_DEF_INTEGER,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "atIfIndex"
- },
- { ATF_NOFLAGS, 0, offsetof(struct AtEntry, atPhysAddress),
- (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)),
- 0,
- &asn_DEF_PhysAddress,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "atPhysAddress"
- },
- { ATF_NOFLAGS, 0, offsetof(struct AtEntry, atNetAddress),
- -1 /* Ambiguous tag (CHOICE?) */,
- 0,
- &asn_DEF_NetworkAddress,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "atNetAddress"
- },
-};
-static ber_tlv_tag_t asn_DEF_AtEntry_tags_1[] = {
- (ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
-};
-static asn_TYPE_tag2member_t asn_MAP_AtEntry_tag2el_1[] = {
- { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 0 }, /* atIfIndex at 154 */
- { (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 1, 0, 0 }, /* atPhysAddress at 157 */
- { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 2, 0, 0 } /* internet at 113 */
-};
-static asn_SEQUENCE_specifics_t asn_SPC_AtEntry_specs_1 = {
- sizeof(struct AtEntry),
- offsetof(struct AtEntry, _asn_ctx),
- asn_MAP_AtEntry_tag2el_1,
- 3, /* Count of tags in the map */
- 0, 0, 0, /* Optional elements (not needed) */
- -1, /* Start extensions */
- -1 /* Stop extensions */
-};
-asn_TYPE_descriptor_t asn_DEF_AtEntry = {
- "AtEntry",
- "AtEntry",
- SEQUENCE_free,
- SEQUENCE_print,
- SEQUENCE_constraint,
- SEQUENCE_decode_ber,
- SEQUENCE_encode_der,
- SEQUENCE_decode_xer,
- SEQUENCE_encode_xer,
- 0, 0, /* No PER support, use "-gen-PER" to enable */
- 0, /* Use generic outmost tag fetcher */
- asn_DEF_AtEntry_tags_1,
- sizeof(asn_DEF_AtEntry_tags_1)
- /sizeof(asn_DEF_AtEntry_tags_1[0]), /* 1 */
- asn_DEF_AtEntry_tags_1, /* Same as above */
- sizeof(asn_DEF_AtEntry_tags_1)
- /sizeof(asn_DEF_AtEntry_tags_1[0]), /* 1 */
- 0, /* No PER visible constraints */
- asn_MBR_AtEntry_1,
- 3, /* Elements count */
- &asn_SPC_AtEntry_specs_1 /* Additional specs */
-};
-
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1213-MIB"
- * found in "RFC1213-MIB.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#ifndef _AtEntry_H_
-#define _AtEntry_H_
-
-
-#include <asn_application.h>
-
-/* Including external dependencies */
-#include <INTEGER.h>
-#include "PhysAddress.h"
-#include "NetworkAddress.h"
-#include <constr_SEQUENCE.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* AtEntry */
-typedef struct AtEntry {
- INTEGER_t atIfIndex;
- PhysAddress_t atPhysAddress;
- NetworkAddress_t atNetAddress;
-
- /* Context for parsing across buffer boundaries */
- asn_struct_ctx_t _asn_ctx;
-} AtEntry_t;
-
-/* Implementation */
-extern asn_TYPE_descriptor_t asn_DEF_AtEntry;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _AtEntry_H_ */
+++ /dev/null
-/*-
- * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-#include <asn_internal.h>
-#include <BIT_STRING.h>
-#include <asn_internal.h>
-
-/*
- * BIT STRING basic type description.
- */
-static ber_tlv_tag_t asn_DEF_BIT_STRING_tags[] = {
- (ASN_TAG_CLASS_UNIVERSAL | (3 << 2))
-};
-static asn_OCTET_STRING_specifics_t asn_DEF_BIT_STRING_specs = {
- sizeof(BIT_STRING_t),
- offsetof(BIT_STRING_t, _asn_ctx),
- 1, /* Special indicator that this is a BIT STRING type */
-};
-asn_TYPE_descriptor_t asn_DEF_BIT_STRING = {
- "BIT STRING",
- "BIT_STRING",
- OCTET_STRING_free, /* Implemented in terms of OCTET STRING */
- BIT_STRING_print,
- BIT_STRING_constraint,
- OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */
- OCTET_STRING_encode_der, /* Implemented in terms of OCTET STRING */
- OCTET_STRING_decode_xer_binary,
- BIT_STRING_encode_xer,
- OCTET_STRING_decode_uper, /* Unaligned PER decoder */
- OCTET_STRING_encode_uper, /* Unaligned PER encoder */
- 0, /* Use generic outmost tag fetcher */
- asn_DEF_BIT_STRING_tags,
- sizeof(asn_DEF_BIT_STRING_tags)
- / sizeof(asn_DEF_BIT_STRING_tags[0]),
- asn_DEF_BIT_STRING_tags, /* Same as above */
- sizeof(asn_DEF_BIT_STRING_tags)
- / sizeof(asn_DEF_BIT_STRING_tags[0]),
- 0, /* No PER visible constraints */
- 0, 0, /* No members */
- &asn_DEF_BIT_STRING_specs
-};
-
-/*
- * BIT STRING generic constraint.
- */
-int
-BIT_STRING_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
- asn_app_constraint_failed_f *ctfailcb, void *app_key) {
- const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;
-
- if(st && st->buf) {
- if(st->size == 1 && st->bits_unused) {
- _ASN_CTFAIL(app_key, td,
- "%s: invalid padding byte (%s:%d)",
- td->name, __FILE__, __LINE__);
- return -1;
- }
- } else {
- _ASN_CTFAIL(app_key, td,
- "%s: value not given (%s:%d)",
- td->name, __FILE__, __LINE__);
- return -1;
- }
-
- return 0;
-}
-
-static char *_bit_pattern[16] = {
- "0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111",
- "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"
-};
-
-asn_enc_rval_t
-BIT_STRING_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
- int ilevel, enum xer_encoder_flags_e flags,
- asn_app_consume_bytes_f *cb, void *app_key) {
- asn_enc_rval_t er;
- char scratch[128];
- char *p = scratch;
- char *scend = scratch + (sizeof(scratch) - 10);
- const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;
- int xcan = (flags & XER_F_CANONICAL);
- uint8_t *buf;
- uint8_t *end;
-
- if(!st || !st->buf)
- _ASN_ENCODE_FAILED;
-
- er.encoded = 0;
-
- buf = st->buf;
- end = buf + st->size - 1; /* Last byte is special */
-
- /*
- * Binary dump
- */
- for(; buf < end; buf++) {
- int v = *buf;
- int nline = xcan?0:(((buf - st->buf) % 8) == 0);
- if(p >= scend || nline) {
- er.encoded += p - scratch;
- _ASN_CALLBACK(scratch, p - scratch);
- p = scratch;
- if(nline) _i_ASN_TEXT_INDENT(1, ilevel);
- }
- memcpy(p + 0, _bit_pattern[v >> 4], 4);
- memcpy(p + 4, _bit_pattern[v & 0x0f], 4);
- p += 8;
- }
-
- if(!xcan && ((buf - st->buf) % 8) == 0)
- _i_ASN_TEXT_INDENT(1, ilevel);
- er.encoded += p - scratch;
- _ASN_CALLBACK(scratch, p - scratch);
- p = scratch;
-
- if(buf == end) {
- int v = *buf;
- int ubits = st->bits_unused;
- int i;
- for(i = 7; i >= ubits; i--)
- *p++ = (v & (1 << i)) ? 0x31 : 0x30;
- er.encoded += p - scratch;
- _ASN_CALLBACK(scratch, p - scratch);
- }
-
- if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel - 1);
-
- _ASN_ENCODED_OK(er);
-cb_failed:
- _ASN_ENCODE_FAILED;
-}
-
-
-/*
- * BIT STRING specific contents printer.
- */
-int
-BIT_STRING_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
- asn_app_consume_bytes_f *cb, void *app_key) {
- static const char *h2c = "0123456789ABCDEF";
- char scratch[64];
- const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;
- uint8_t *buf;
- uint8_t *end;
- char *p = scratch;
-
- (void)td; /* Unused argument */
-
- if(!st || !st->buf)
- return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
-
- ilevel++;
- buf = st->buf;
- end = buf + st->size;
-
- /*
- * Hexadecimal dump.
- */
- for(; buf < end; buf++) {
- if((buf - st->buf) % 16 == 0 && (st->size > 16)
- && buf != st->buf) {
- _i_INDENT(1);
- /* Dump the string */
- if(cb(scratch, p - scratch, app_key) < 0) return -1;
- p = scratch;
- }
- *p++ = h2c[*buf >> 4];
- *p++ = h2c[*buf & 0x0F];
- *p++ = 0x20;
- }
-
- if(p > scratch) {
- p--; /* Eat the tailing space */
-
- if((st->size > 16)) {
- _i_INDENT(1);
- }
-
- /* Dump the incomplete 16-bytes row */
- if(cb(scratch, p - scratch, app_key) < 0)
- return -1;
- }
-
- return 0;
-}
-
+++ /dev/null
-/*-
- * Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-#ifndef _BIT_STRING_H_
-#define _BIT_STRING_H_
-
-#include <OCTET_STRING.h> /* Some help from OCTET STRING */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct BIT_STRING_s {
- uint8_t *buf; /* BIT STRING body */
- int size; /* Size of the above buffer */
-
- int bits_unused;/* Unused trailing bits in the last octet (0..7) */
-
- asn_struct_ctx_t _asn_ctx; /* Parsing across buffer boundaries */
-} BIT_STRING_t;
-
-extern asn_TYPE_descriptor_t asn_DEF_BIT_STRING;
-
-asn_struct_print_f BIT_STRING_print; /* Human-readable output */
-asn_constr_check_f BIT_STRING_constraint;
-xer_type_encoder_f BIT_STRING_encode_xer;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _BIT_STRING_H_ */
+++ /dev/null
-/*-
- * Copyright (c) 2003, 2005 Lev Walkin <vlm@lionet.info>. All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-#include <asn_internal.h>
-#include <asn_codecs_prim.h>
-#include <BOOLEAN.h>
-
-/*
- * BOOLEAN basic type description.
- */
-static ber_tlv_tag_t asn_DEF_BOOLEAN_tags[] = {
- (ASN_TAG_CLASS_UNIVERSAL | (1 << 2))
-};
-asn_TYPE_descriptor_t asn_DEF_BOOLEAN = {
- "BOOLEAN",
- "BOOLEAN",
- BOOLEAN_free,
- BOOLEAN_print,
- asn_generic_no_constraint,
- BOOLEAN_decode_ber,
- BOOLEAN_encode_der,
- BOOLEAN_decode_xer,
- BOOLEAN_encode_xer,
- BOOLEAN_decode_uper, /* Unaligned PER decoder */
- BOOLEAN_encode_uper, /* Unaligned PER encoder */
- 0, /* Use generic outmost tag fetcher */
- asn_DEF_BOOLEAN_tags,
- sizeof(asn_DEF_BOOLEAN_tags) / sizeof(asn_DEF_BOOLEAN_tags[0]),
- asn_DEF_BOOLEAN_tags, /* Same as above */
- sizeof(asn_DEF_BOOLEAN_tags) / sizeof(asn_DEF_BOOLEAN_tags[0]),
- 0, /* No PER visible constraints */
- 0, 0, /* No members */
- 0 /* No specifics */
-};
-
-/*
- * Decode BOOLEAN type.
- */
-asn_dec_rval_t
-BOOLEAN_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
- asn_TYPE_descriptor_t *td,
- void **bool_value, const void *buf_ptr, size_t size,
- int tag_mode) {
- BOOLEAN_t *st = (BOOLEAN_t *)*bool_value;
- asn_dec_rval_t rval;
- ber_tlv_len_t length;
- ber_tlv_len_t lidx;
-
- if(st == NULL) {
- st = (BOOLEAN_t *)(*bool_value = CALLOC(1, sizeof(*st)));
- if(st == NULL) {
- rval.code = RC_FAIL;
- rval.consumed = 0;
- return rval;
- }
- }
-
- ASN_DEBUG("Decoding %s as BOOLEAN (tm=%d)",
- td->name, tag_mode);
-
- /*
- * Check tags.
- */
- rval = ber_check_tags(opt_codec_ctx, td, 0, buf_ptr, size,
- tag_mode, 0, &length, 0);
- if(rval.code != RC_OK)
- return rval;
-
- ASN_DEBUG("Boolean length is %d bytes", (int)length);
-
- buf_ptr = ((const char *)buf_ptr) + rval.consumed;
- size -= rval.consumed;
- if(length > (ber_tlv_len_t)size) {
- rval.code = RC_WMORE;
- rval.consumed = 0;
- return rval;
- }
-
- /*
- * Compute boolean value.
- */
- for(*st = 0, lidx = 0;
- (lidx < length) && *st == 0; lidx++) {
- /*
- * Very simple approach: read bytes until the end or
- * value is already TRUE.
- * BOOLEAN is not supposed to contain meaningful data anyway.
- */
- *st |= ((const uint8_t *)buf_ptr)[lidx];
- }
-
- rval.code = RC_OK;
- rval.consumed += length;
-
- ASN_DEBUG("Took %ld/%ld bytes to encode %s, value=%d",
- (long)rval.consumed, (long)length,
- td->name, *st);
-
- return rval;
-}
-
-asn_enc_rval_t
-BOOLEAN_encode_der(asn_TYPE_descriptor_t *td, void *sptr,
- int tag_mode, ber_tlv_tag_t tag,
- asn_app_consume_bytes_f *cb, void *app_key) {
- asn_enc_rval_t erval;
- BOOLEAN_t *st = (BOOLEAN_t *)sptr;
-
- erval.encoded = der_write_tags(td, 1, tag_mode, 0, tag, cb, app_key);
- if(erval.encoded == -1) {
- erval.failed_type = td;
- erval.structure_ptr = sptr;
- return erval;
- }
-
- if(cb) {
- uint8_t bool_value;
-
- bool_value = *st ? 0xff : 0; /* 0xff mandated by DER */
-
- if(cb(&bool_value, 1, app_key) < 0) {
- erval.encoded = -1;
- erval.failed_type = td;
- erval.structure_ptr = sptr;
- return erval;
- }
- }
-
- erval.encoded += 1;
-
- _ASN_ENCODED_OK(erval);
-}
-
-
-/*
- * Decode the chunk of XML text encoding INTEGER.
- */
-static enum xer_pbd_rval
-BOOLEAN__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chunk_buf, size_t chunk_size) {
- BOOLEAN_t *st = (BOOLEAN_t *)sptr;
- const char *p = (const char *)chunk_buf;
-
- (void)td;
-
- if(chunk_size && p[0] == 0x3c /* '<' */) {
- switch(xer_check_tag(chunk_buf, chunk_size, "false")) {
- case XCT_BOTH:
- /* "<false/>" */
- *st = 0;
- break;
- case XCT_UNKNOWN_BO:
- if(xer_check_tag(chunk_buf, chunk_size, "true")
- != XCT_BOTH)
- return XPBD_BROKEN_ENCODING;
- /* "<true/>" */
- *st = 1; /* Or 0xff as in DER?.. */
- break;
- default:
- return XPBD_BROKEN_ENCODING;
- }
- return XPBD_BODY_CONSUMED;
- } else {
- if(xer_is_whitespace(chunk_buf, chunk_size))
- return XPBD_NOT_BODY_IGNORE;
- else
- return XPBD_BROKEN_ENCODING;
- }
-}
-
-
-asn_dec_rval_t
-BOOLEAN_decode_xer(asn_codec_ctx_t *opt_codec_ctx,
- asn_TYPE_descriptor_t *td, void **sptr, const char *opt_mname,
- const void *buf_ptr, size_t size) {
-
- return xer_decode_primitive(opt_codec_ctx, td,
- sptr, sizeof(BOOLEAN_t), opt_mname, buf_ptr, size,
- BOOLEAN__xer_body_decode);
-}
-
-asn_enc_rval_t
-BOOLEAN_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
- int ilevel, enum xer_encoder_flags_e flags,
- asn_app_consume_bytes_f *cb, void *app_key) {
- const BOOLEAN_t *st = (const BOOLEAN_t *)sptr;
- asn_enc_rval_t er;
-
- (void)ilevel;
- (void)flags;
-
- if(!st) _ASN_ENCODE_FAILED;
-
- if(*st) {
- _ASN_CALLBACK("<true/>", 7);
- er.encoded = 7;
- } else {
- _ASN_CALLBACK("<false/>", 8);
- er.encoded = 8;
- }
-
- _ASN_ENCODED_OK(er);
-cb_failed:
- _ASN_ENCODE_FAILED;
-}
-
-int
-BOOLEAN_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
- asn_app_consume_bytes_f *cb, void *app_key) {
- const BOOLEAN_t *st = (const BOOLEAN_t *)sptr;
- const char *buf;
- size_t buflen;
-
- (void)td; /* Unused argument */
- (void)ilevel; /* Unused argument */
-
- if(st) {
- if(*st) {
- buf = "TRUE";
- buflen = 4;
- } else {
- buf = "FALSE";
- buflen = 5;
- }
- } else {
- buf = "<absent>";
- buflen = 8;
- }
-
- return (cb(buf, buflen, app_key) < 0) ? -1 : 0;
-}
-
-void
-BOOLEAN_free(asn_TYPE_descriptor_t *td, void *ptr, int contents_only) {
- if(td && ptr && !contents_only) {
- FREEMEM(ptr);
- }
-}
-
-asn_dec_rval_t
-BOOLEAN_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
- asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
- asn_dec_rval_t rv;
- BOOLEAN_t *st = (BOOLEAN_t *)*sptr;
-
- (void)opt_codec_ctx;
- (void)constraints;
-
- if(!st) {
- st = (BOOLEAN_t *)(*sptr = MALLOC(sizeof(*st)));
- if(!st) _ASN_DECODE_FAILED;
- }
-
- /*
- * Extract a single bit
- */
- switch(per_get_few_bits(pd, 1)) {
- case 1: *st = 1; break;
- case 0: *st = 0; break;
- case -1: default: _ASN_DECODE_FAILED;
- }
-
- ASN_DEBUG("%s decoded as %s", td->name, *st ? "TRUE" : "FALSE");
-
- rv.code = RC_OK;
- rv.consumed = 1;
- return rv;
-}
-
-
-asn_enc_rval_t
-BOOLEAN_encode_uper(asn_TYPE_descriptor_t *td,
- asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
- const BOOLEAN_t *st = (const BOOLEAN_t *)sptr;
- asn_enc_rval_t er;
-
- (void)constraints;
-
- if(!st) _ASN_ENCODE_FAILED;
-
- per_put_few_bits(po, *st ? 1 : 0, 1);
-
- _ASN_ENCODED_OK(er);
-}
+++ /dev/null
-/*-
- * Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-#ifndef _BOOLEAN_H_
-#define _BOOLEAN_H_
-
-#include <asn_application.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * The underlying integer may contain various values, but everything
- * non-zero is capped to 0xff by the DER encoder. The BER decoder may
- * yield non-zero values different from 1, beware.
- */
-typedef int BOOLEAN_t;
-
-extern asn_TYPE_descriptor_t asn_DEF_BOOLEAN;
-
-asn_struct_free_f BOOLEAN_free;
-asn_struct_print_f BOOLEAN_print;
-ber_type_decoder_f BOOLEAN_decode_ber;
-der_type_encoder_f BOOLEAN_encode_der;
-xer_type_decoder_f BOOLEAN_decode_xer;
-xer_type_encoder_f BOOLEAN_encode_xer;
-per_type_decoder_f BOOLEAN_decode_uper;
-per_type_encoder_f BOOLEAN_encode_uper;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _BOOLEAN_H_ */
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "SMUX"
- * found in "SMUX.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#include <asn_internal.h>
-
-#include "ClosePDU.h"
-
-int
-ClosePDU_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
- asn_app_constraint_failed_f *ctfailcb, void *app_key) {
- /* Replace with underlying type checker */
- td->check_constraints = asn_DEF_INTEGER.check_constraints;
- return td->check_constraints(td, sptr, ctfailcb, app_key);
-}
-
-/*
- * This type is implemented using INTEGER,
- * so here we adjust the DEF accordingly.
- */
-static void
-ClosePDU_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
- td->free_struct = asn_DEF_INTEGER.free_struct;
- td->print_struct = asn_DEF_INTEGER.print_struct;
- td->ber_decoder = asn_DEF_INTEGER.ber_decoder;
- td->der_encoder = asn_DEF_INTEGER.der_encoder;
- td->xer_decoder = asn_DEF_INTEGER.xer_decoder;
- td->xer_encoder = asn_DEF_INTEGER.xer_encoder;
- td->uper_decoder = asn_DEF_INTEGER.uper_decoder;
- td->uper_encoder = asn_DEF_INTEGER.uper_encoder;
- if(!td->per_constraints)
- td->per_constraints = asn_DEF_INTEGER.per_constraints;
- td->elements = asn_DEF_INTEGER.elements;
- td->elements_count = asn_DEF_INTEGER.elements_count;
- td->specifics = asn_DEF_INTEGER.specifics;
-}
-
-void
-ClosePDU_free(asn_TYPE_descriptor_t *td,
- void *struct_ptr, int contents_only) {
- ClosePDU_1_inherit_TYPE_descriptor(td);
- td->free_struct(td, struct_ptr, contents_only);
-}
-
-int
-ClosePDU_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
- int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
- ClosePDU_1_inherit_TYPE_descriptor(td);
- return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
-}
-
-asn_dec_rval_t
-ClosePDU_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
- void **structure, const void *bufptr, size_t size, int tag_mode) {
- ClosePDU_1_inherit_TYPE_descriptor(td);
- return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode);
-}
-
-asn_enc_rval_t
-ClosePDU_encode_der(asn_TYPE_descriptor_t *td,
- void *structure, int tag_mode, ber_tlv_tag_t tag,
- asn_app_consume_bytes_f *cb, void *app_key) {
- ClosePDU_1_inherit_TYPE_descriptor(td);
- return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
-}
-
-asn_dec_rval_t
-ClosePDU_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
- void **structure, const char *opt_mname, const void *bufptr, size_t size) {
- ClosePDU_1_inherit_TYPE_descriptor(td);
- return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size);
-}
-
-asn_enc_rval_t
-ClosePDU_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
- int ilevel, enum xer_encoder_flags_e flags,
- asn_app_consume_bytes_f *cb, void *app_key) {
- ClosePDU_1_inherit_TYPE_descriptor(td);
- return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
-}
-
-static ber_tlv_tag_t asn_DEF_ClosePDU_tags_1[] = {
- (ASN_TAG_CLASS_APPLICATION | (1 << 2)),
- (ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
-};
-asn_TYPE_descriptor_t asn_DEF_ClosePDU = {
- "ClosePDU",
- "ClosePDU",
- ClosePDU_free,
- ClosePDU_print,
- ClosePDU_constraint,
- ClosePDU_decode_ber,
- ClosePDU_encode_der,
- ClosePDU_decode_xer,
- ClosePDU_encode_xer,
- 0, 0, /* No PER support, use "-gen-PER" to enable */
- 0, /* Use generic outmost tag fetcher */
- asn_DEF_ClosePDU_tags_1,
- sizeof(asn_DEF_ClosePDU_tags_1)
- /sizeof(asn_DEF_ClosePDU_tags_1[0]) - 1, /* 1 */
- asn_DEF_ClosePDU_tags_1, /* Same as above */
- sizeof(asn_DEF_ClosePDU_tags_1)
- /sizeof(asn_DEF_ClosePDU_tags_1[0]), /* 2 */
- 0, /* No PER visible constraints */
- 0, 0, /* Defined elsewhere */
- 0 /* No specifics */
-};
-
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "SMUX"
- * found in "SMUX.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#ifndef _ClosePDU_H_
-#define _ClosePDU_H_
-
-
-#include <asn_application.h>
-
-/* Including external dependencies */
-#include <INTEGER.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Dependencies */
-typedef enum ClosePDU {
- ClosePDU_goingDown = 0,
- ClosePDU_unsupportedVersion = 1,
- ClosePDU_packetFormat = 2,
- ClosePDU_protocolError = 3,
- ClosePDU_internalError = 4,
- ClosePDU_authenticationFailure = 5
-} e_ClosePDU;
-
-/* ClosePDU */
-typedef INTEGER_t ClosePDU_t;
-
-/* Implementation */
-extern asn_TYPE_descriptor_t asn_DEF_ClosePDU;
-asn_struct_free_f ClosePDU_free;
-asn_struct_print_f ClosePDU_print;
-asn_constr_check_f ClosePDU_constraint;
-ber_type_decoder_f ClosePDU_decode_ber;
-der_type_encoder_f ClosePDU_encode_der;
-xer_type_decoder_f ClosePDU_decode_xer;
-xer_type_encoder_f ClosePDU_encode_xer;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _ClosePDU_H_ */
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1155-SMI"
- * found in "RFC1155-SMI.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#include <asn_internal.h>
-
-#include "Counter.h"
-
-int
-Counter_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
- asn_app_constraint_failed_f *ctfailcb, void *app_key) {
- const INTEGER_t *st = (const INTEGER_t *)sptr;
- long value;
-
- if(!sptr) {
- _ASN_CTFAIL(app_key, td, sptr,
- "%s: value not given (%s:%d)",
- td->name, __FILE__, __LINE__);
- return -1;
- }
-
- if(asn_INTEGER2long(st, &value)) {
- _ASN_CTFAIL(app_key, td, sptr,
- "%s: value too large (%s:%d)",
- td->name, __FILE__, __LINE__);
- return -1;
- }
-
- if((value >= 0 && value <= 4294967295)) {
- /* Constraint check succeeded */
- return 0;
- } else {
- _ASN_CTFAIL(app_key, td, sptr,
- "%s: constraint failed (%s:%d)",
- td->name, __FILE__, __LINE__);
- return -1;
- }
-}
-
-/*
- * This type is implemented using INTEGER,
- * so here we adjust the DEF accordingly.
- */
-static void
-Counter_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
- td->free_struct = asn_DEF_INTEGER.free_struct;
- td->print_struct = asn_DEF_INTEGER.print_struct;
- td->ber_decoder = asn_DEF_INTEGER.ber_decoder;
- td->der_encoder = asn_DEF_INTEGER.der_encoder;
- td->xer_decoder = asn_DEF_INTEGER.xer_decoder;
- td->xer_encoder = asn_DEF_INTEGER.xer_encoder;
- td->uper_decoder = asn_DEF_INTEGER.uper_decoder;
- td->uper_encoder = asn_DEF_INTEGER.uper_encoder;
- if(!td->per_constraints)
- td->per_constraints = asn_DEF_INTEGER.per_constraints;
- td->elements = asn_DEF_INTEGER.elements;
- td->elements_count = asn_DEF_INTEGER.elements_count;
- td->specifics = asn_DEF_INTEGER.specifics;
-}
-
-void
-Counter_free(asn_TYPE_descriptor_t *td,
- void *struct_ptr, int contents_only) {
- Counter_1_inherit_TYPE_descriptor(td);
- td->free_struct(td, struct_ptr, contents_only);
-}
-
-int
-Counter_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
- int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
- Counter_1_inherit_TYPE_descriptor(td);
- return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
-}
-
-asn_dec_rval_t
-Counter_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
- void **structure, const void *bufptr, size_t size, int tag_mode) {
- Counter_1_inherit_TYPE_descriptor(td);
- return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode);
-}
-
-asn_enc_rval_t
-Counter_encode_der(asn_TYPE_descriptor_t *td,
- void *structure, int tag_mode, ber_tlv_tag_t tag,
- asn_app_consume_bytes_f *cb, void *app_key) {
- Counter_1_inherit_TYPE_descriptor(td);
- return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
-}
-
-asn_dec_rval_t
-Counter_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
- void **structure, const char *opt_mname, const void *bufptr, size_t size) {
- Counter_1_inherit_TYPE_descriptor(td);
- return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size);
-}
-
-asn_enc_rval_t
-Counter_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
- int ilevel, enum xer_encoder_flags_e flags,
- asn_app_consume_bytes_f *cb, void *app_key) {
- Counter_1_inherit_TYPE_descriptor(td);
- return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
-}
-
-static ber_tlv_tag_t asn_DEF_Counter_tags_1[] = {
- (ASN_TAG_CLASS_APPLICATION | (1 << 2)),
- (ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
-};
-asn_TYPE_descriptor_t asn_DEF_Counter = {
- "Counter",
- "Counter",
- Counter_free,
- Counter_print,
- Counter_constraint,
- Counter_decode_ber,
- Counter_encode_der,
- Counter_decode_xer,
- Counter_encode_xer,
- 0, 0, /* No PER support, use "-gen-PER" to enable */
- 0, /* Use generic outmost tag fetcher */
- asn_DEF_Counter_tags_1,
- sizeof(asn_DEF_Counter_tags_1)
- /sizeof(asn_DEF_Counter_tags_1[0]) - 1, /* 1 */
- asn_DEF_Counter_tags_1, /* Same as above */
- sizeof(asn_DEF_Counter_tags_1)
- /sizeof(asn_DEF_Counter_tags_1[0]), /* 2 */
- 0, /* No PER visible constraints */
- 0, 0, /* No members */
- 0 /* No specifics */
-};
-
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1155-SMI"
- * found in "RFC1155-SMI.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#ifndef _Counter_H_
-#define _Counter_H_
-
-
-#include <asn_application.h>
-
-/* Including external dependencies */
-#include <INTEGER.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Counter */
-typedef INTEGER_t Counter_t;
-
-/* Implementation */
-extern asn_TYPE_descriptor_t asn_DEF_Counter;
-asn_struct_free_f Counter_free;
-asn_struct_print_f Counter_print;
-asn_constr_check_f Counter_constraint;
-ber_type_decoder_f Counter_decode_ber;
-der_type_encoder_f Counter_encode_der;
-xer_type_decoder_f Counter_decode_xer;
-xer_type_encoder_f Counter_encode_xer;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _Counter_H_ */
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1213-MIB"
- * found in "RFC1213-MIB.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#include <asn_internal.h>
-
-#include "DisplayString.h"
-
-int
-DisplayString_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
- asn_app_constraint_failed_f *ctfailcb, void *app_key) {
- /* Replace with underlying type checker */
- td->check_constraints = asn_DEF_OCTET_STRING.check_constraints;
- return td->check_constraints(td, sptr, ctfailcb, app_key);
-}
-
-/*
- * This type is implemented using OCTET_STRING,
- * so here we adjust the DEF accordingly.
- */
-static void
-DisplayString_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
- td->free_struct = asn_DEF_OCTET_STRING.free_struct;
- td->print_struct = asn_DEF_OCTET_STRING.print_struct;
- td->ber_decoder = asn_DEF_OCTET_STRING.ber_decoder;
- td->der_encoder = asn_DEF_OCTET_STRING.der_encoder;
- td->xer_decoder = asn_DEF_OCTET_STRING.xer_decoder;
- td->xer_encoder = asn_DEF_OCTET_STRING.xer_encoder;
- td->uper_decoder = asn_DEF_OCTET_STRING.uper_decoder;
- td->uper_encoder = asn_DEF_OCTET_STRING.uper_encoder;
- if(!td->per_constraints)
- td->per_constraints = asn_DEF_OCTET_STRING.per_constraints;
- td->elements = asn_DEF_OCTET_STRING.elements;
- td->elements_count = asn_DEF_OCTET_STRING.elements_count;
- td->specifics = asn_DEF_OCTET_STRING.specifics;
-}
-
-void
-DisplayString_free(asn_TYPE_descriptor_t *td,
- void *struct_ptr, int contents_only) {
- DisplayString_1_inherit_TYPE_descriptor(td);
- td->free_struct(td, struct_ptr, contents_only);
-}
-
-int
-DisplayString_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
- int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
- DisplayString_1_inherit_TYPE_descriptor(td);
- return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
-}
-
-asn_dec_rval_t
-DisplayString_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
- void **structure, const void *bufptr, size_t size, int tag_mode) {
- DisplayString_1_inherit_TYPE_descriptor(td);
- return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode);
-}
-
-asn_enc_rval_t
-DisplayString_encode_der(asn_TYPE_descriptor_t *td,
- void *structure, int tag_mode, ber_tlv_tag_t tag,
- asn_app_consume_bytes_f *cb, void *app_key) {
- DisplayString_1_inherit_TYPE_descriptor(td);
- return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
-}
-
-asn_dec_rval_t
-DisplayString_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
- void **structure, const char *opt_mname, const void *bufptr, size_t size) {
- DisplayString_1_inherit_TYPE_descriptor(td);
- return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size);
-}
-
-asn_enc_rval_t
-DisplayString_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
- int ilevel, enum xer_encoder_flags_e flags,
- asn_app_consume_bytes_f *cb, void *app_key) {
- DisplayString_1_inherit_TYPE_descriptor(td);
- return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
-}
-
-static ber_tlv_tag_t asn_DEF_DisplayString_tags_1[] = {
- (ASN_TAG_CLASS_UNIVERSAL | (4 << 2))
-};
-asn_TYPE_descriptor_t asn_DEF_DisplayString = {
- "DisplayString",
- "DisplayString",
- DisplayString_free,
- DisplayString_print,
- DisplayString_constraint,
- DisplayString_decode_ber,
- DisplayString_encode_der,
- DisplayString_decode_xer,
- DisplayString_encode_xer,
- 0, 0, /* No PER support, use "-gen-PER" to enable */
- 0, /* Use generic outmost tag fetcher */
- asn_DEF_DisplayString_tags_1,
- sizeof(asn_DEF_DisplayString_tags_1)
- /sizeof(asn_DEF_DisplayString_tags_1[0]), /* 1 */
- asn_DEF_DisplayString_tags_1, /* Same as above */
- sizeof(asn_DEF_DisplayString_tags_1)
- /sizeof(asn_DEF_DisplayString_tags_1[0]), /* 1 */
- 0, /* No PER visible constraints */
- 0, 0, /* No members */
- 0 /* No specifics */
-};
-
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1213-MIB"
- * found in "RFC1213-MIB.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#ifndef _DisplayString_H_
-#define _DisplayString_H_
-
-
-#include <asn_application.h>
-
-/* Including external dependencies */
-#include <OCTET_STRING.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* DisplayString */
-typedef OCTET_STRING_t DisplayString_t;
-
-/* Implementation */
-extern asn_TYPE_descriptor_t asn_DEF_DisplayString;
-asn_struct_free_f DisplayString_free;
-asn_struct_print_f DisplayString_print;
-asn_constr_check_f DisplayString_constraint;
-ber_type_decoder_f DisplayString_decode_ber;
-der_type_encoder_f DisplayString_encode_der;
-xer_type_decoder_f DisplayString_decode_xer;
-xer_type_encoder_f DisplayString_encode_xer;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _DisplayString_H_ */
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1213-MIB"
- * found in "RFC1213-MIB.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#include <asn_internal.h>
-
-#include "EgpNeighEntry.h"
-
-static asn_TYPE_member_t asn_MBR_EgpNeighEntry_1[] = {
- { ATF_NOFLAGS, 0, offsetof(struct EgpNeighEntry, egpNeighState),
- (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
- 0,
- &asn_DEF_INTEGER,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "egpNeighState"
- },
- { ATF_NOFLAGS, 0, offsetof(struct EgpNeighEntry, egpNeighAddr),
- (ASN_TAG_CLASS_APPLICATION | (0 << 2)),
- 0,
- &asn_DEF_IpAddress,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "egpNeighAddr"
- },
- { ATF_NOFLAGS, 0, offsetof(struct EgpNeighEntry, egpNeighAs),
- (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
- 0,
- &asn_DEF_INTEGER,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "egpNeighAs"
- },
- { ATF_NOFLAGS, 0, offsetof(struct EgpNeighEntry, egpNeighInMsgs),
- (ASN_TAG_CLASS_APPLICATION | (1 << 2)),
- 0,
- &asn_DEF_Counter,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "egpNeighInMsgs"
- },
- { ATF_NOFLAGS, 0, offsetof(struct EgpNeighEntry, egpNeighInErrs),
- (ASN_TAG_CLASS_APPLICATION | (1 << 2)),
- 0,
- &asn_DEF_Counter,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "egpNeighInErrs"
- },
- { ATF_NOFLAGS, 0, offsetof(struct EgpNeighEntry, egpNeighOutMsgs),
- (ASN_TAG_CLASS_APPLICATION | (1 << 2)),
- 0,
- &asn_DEF_Counter,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "egpNeighOutMsgs"
- },
- { ATF_NOFLAGS, 0, offsetof(struct EgpNeighEntry, egpNeighOutErrs),
- (ASN_TAG_CLASS_APPLICATION | (1 << 2)),
- 0,
- &asn_DEF_Counter,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "egpNeighOutErrs"
- },
- { ATF_NOFLAGS, 0, offsetof(struct EgpNeighEntry, egpNeighInErrMsgs),
- (ASN_TAG_CLASS_APPLICATION | (1 << 2)),
- 0,
- &asn_DEF_Counter,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "egpNeighInErrMsgs"
- },
- { ATF_NOFLAGS, 0, offsetof(struct EgpNeighEntry, egpNeighOutErrMsgs),
- (ASN_TAG_CLASS_APPLICATION | (1 << 2)),
- 0,
- &asn_DEF_Counter,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "egpNeighOutErrMsgs"
- },
- { ATF_NOFLAGS, 0, offsetof(struct EgpNeighEntry, egpNeighStateUps),
- (ASN_TAG_CLASS_APPLICATION | (1 << 2)),
- 0,
- &asn_DEF_Counter,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "egpNeighStateUps"
- },
- { ATF_NOFLAGS, 0, offsetof(struct EgpNeighEntry, egpNeighStateDowns),
- (ASN_TAG_CLASS_APPLICATION | (1 << 2)),
- 0,
- &asn_DEF_Counter,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "egpNeighStateDowns"
- },
- { ATF_NOFLAGS, 0, offsetof(struct EgpNeighEntry, egpNeighIntervalHello),
- (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
- 0,
- &asn_DEF_INTEGER,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "egpNeighIntervalHello"
- },
- { ATF_NOFLAGS, 0, offsetof(struct EgpNeighEntry, egpNeighIntervalPoll),
- (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
- 0,
- &asn_DEF_INTEGER,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "egpNeighIntervalPoll"
- },
- { ATF_NOFLAGS, 0, offsetof(struct EgpNeighEntry, egpNeighMode),
- (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
- 0,
- &asn_DEF_INTEGER,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "egpNeighMode"
- },
- { ATF_NOFLAGS, 0, offsetof(struct EgpNeighEntry, egpNeighEventTrigger),
- (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
- 0,
- &asn_DEF_INTEGER,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "egpNeighEventTrigger"
- },
-};
-static ber_tlv_tag_t asn_DEF_EgpNeighEntry_tags_1[] = {
- (ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
-};
-static asn_TYPE_tag2member_t asn_MAP_EgpNeighEntry_tag2el_1[] = {
- { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 5 }, /* egpNeighState at 267 */
- { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 2, -1, 4 }, /* egpNeighAs at 271 */
- { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 11, -2, 3 }, /* egpNeighIntervalHello at 290 */
- { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 12, -3, 2 }, /* egpNeighIntervalPoll at 292 */
- { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 13, -4, 1 }, /* egpNeighMode at 294 */
- { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 14, -5, 0 }, /* egpNeighEventTrigger at 297 */
- { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 1, 0, 0 }, /* egpNeighAddr at 269 */
- { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 3, 0, 7 }, /* egpNeighInMsgs at 273 */
- { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 4, -1, 6 }, /* egpNeighInErrs at 275 */
- { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 5, -2, 5 }, /* egpNeighOutMsgs at 277 */
- { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 6, -3, 4 }, /* egpNeighOutErrs at 279 */
- { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 7, -4, 3 }, /* egpNeighInErrMsgs at 282 */
- { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 8, -5, 2 }, /* egpNeighOutErrMsgs at 284 */
- { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 9, -6, 1 }, /* egpNeighStateUps at 286 */
- { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 10, -7, 0 } /* egpNeighStateDowns at 288 */
-};
-static asn_SEQUENCE_specifics_t asn_SPC_EgpNeighEntry_specs_1 = {
- sizeof(struct EgpNeighEntry),
- offsetof(struct EgpNeighEntry, _asn_ctx),
- asn_MAP_EgpNeighEntry_tag2el_1,
- 15, /* Count of tags in the map */
- 0, 0, 0, /* Optional elements (not needed) */
- -1, /* Start extensions */
- -1 /* Stop extensions */
-};
-asn_TYPE_descriptor_t asn_DEF_EgpNeighEntry = {
- "EgpNeighEntry",
- "EgpNeighEntry",
- SEQUENCE_free,
- SEQUENCE_print,
- SEQUENCE_constraint,
- SEQUENCE_decode_ber,
- SEQUENCE_encode_der,
- SEQUENCE_decode_xer,
- SEQUENCE_encode_xer,
- 0, 0, /* No PER support, use "-gen-PER" to enable */
- 0, /* Use generic outmost tag fetcher */
- asn_DEF_EgpNeighEntry_tags_1,
- sizeof(asn_DEF_EgpNeighEntry_tags_1)
- /sizeof(asn_DEF_EgpNeighEntry_tags_1[0]), /* 1 */
- asn_DEF_EgpNeighEntry_tags_1, /* Same as above */
- sizeof(asn_DEF_EgpNeighEntry_tags_1)
- /sizeof(asn_DEF_EgpNeighEntry_tags_1[0]), /* 1 */
- 0, /* No PER visible constraints */
- asn_MBR_EgpNeighEntry_1,
- 15, /* Elements count */
- &asn_SPC_EgpNeighEntry_specs_1 /* Additional specs */
-};
-
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1213-MIB"
- * found in "RFC1213-MIB.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#ifndef _EgpNeighEntry_H_
-#define _EgpNeighEntry_H_
-
-
-#include <asn_application.h>
-
-/* Including external dependencies */
-#include <INTEGER.h>
-#include "IpAddress.h"
-#include "Counter.h"
-#include <constr_SEQUENCE.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* EgpNeighEntry */
-typedef struct EgpNeighEntry {
- INTEGER_t egpNeighState;
- IpAddress_t egpNeighAddr;
- INTEGER_t egpNeighAs;
- Counter_t egpNeighInMsgs;
- Counter_t egpNeighInErrs;
- Counter_t egpNeighOutMsgs;
- Counter_t egpNeighOutErrs;
- Counter_t egpNeighInErrMsgs;
- Counter_t egpNeighOutErrMsgs;
- Counter_t egpNeighStateUps;
- Counter_t egpNeighStateDowns;
- INTEGER_t egpNeighIntervalHello;
- INTEGER_t egpNeighIntervalPoll;
- INTEGER_t egpNeighMode;
- INTEGER_t egpNeighEventTrigger;
-
- /* Context for parsing across buffer boundaries */
- asn_struct_ctx_t _asn_ctx;
-} EgpNeighEntry_t;
-
-/* Implementation */
-extern asn_TYPE_descriptor_t asn_DEF_EgpNeighEntry;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _EgpNeighEntry_H_ */
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1155-SMI"
- * found in "RFC1155-SMI.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#include <asn_internal.h>
-
-#include "Gauge.h"
-
-int
-Gauge_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
- asn_app_constraint_failed_f *ctfailcb, void *app_key) {
- const INTEGER_t *st = (const INTEGER_t *)sptr;
- long value;
-
- if(!sptr) {
- _ASN_CTFAIL(app_key, td, sptr,
- "%s: value not given (%s:%d)",
- td->name, __FILE__, __LINE__);
- return -1;
- }
-
- if(asn_INTEGER2long(st, &value)) {
- _ASN_CTFAIL(app_key, td, sptr,
- "%s: value too large (%s:%d)",
- td->name, __FILE__, __LINE__);
- return -1;
- }
-
- if((value >= 0 && value <= 4294967295)) {
- /* Constraint check succeeded */
- return 0;
- } else {
- _ASN_CTFAIL(app_key, td, sptr,
- "%s: constraint failed (%s:%d)",
- td->name, __FILE__, __LINE__);
- return -1;
- }
-}
-
-/*
- * This type is implemented using INTEGER,
- * so here we adjust the DEF accordingly.
- */
-static void
-Gauge_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
- td->free_struct = asn_DEF_INTEGER.free_struct;
- td->print_struct = asn_DEF_INTEGER.print_struct;
- td->ber_decoder = asn_DEF_INTEGER.ber_decoder;
- td->der_encoder = asn_DEF_INTEGER.der_encoder;
- td->xer_decoder = asn_DEF_INTEGER.xer_decoder;
- td->xer_encoder = asn_DEF_INTEGER.xer_encoder;
- td->uper_decoder = asn_DEF_INTEGER.uper_decoder;
- td->uper_encoder = asn_DEF_INTEGER.uper_encoder;
- if(!td->per_constraints)
- td->per_constraints = asn_DEF_INTEGER.per_constraints;
- td->elements = asn_DEF_INTEGER.elements;
- td->elements_count = asn_DEF_INTEGER.elements_count;
- td->specifics = asn_DEF_INTEGER.specifics;
-}
-
-void
-Gauge_free(asn_TYPE_descriptor_t *td,
- void *struct_ptr, int contents_only) {
- Gauge_1_inherit_TYPE_descriptor(td);
- td->free_struct(td, struct_ptr, contents_only);
-}
-
-int
-Gauge_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
- int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
- Gauge_1_inherit_TYPE_descriptor(td);
- return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
-}
-
-asn_dec_rval_t
-Gauge_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
- void **structure, const void *bufptr, size_t size, int tag_mode) {
- Gauge_1_inherit_TYPE_descriptor(td);
- return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode);
-}
-
-asn_enc_rval_t
-Gauge_encode_der(asn_TYPE_descriptor_t *td,
- void *structure, int tag_mode, ber_tlv_tag_t tag,
- asn_app_consume_bytes_f *cb, void *app_key) {
- Gauge_1_inherit_TYPE_descriptor(td);
- return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
-}
-
-asn_dec_rval_t
-Gauge_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
- void **structure, const char *opt_mname, const void *bufptr, size_t size) {
- Gauge_1_inherit_TYPE_descriptor(td);
- return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size);
-}
-
-asn_enc_rval_t
-Gauge_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
- int ilevel, enum xer_encoder_flags_e flags,
- asn_app_consume_bytes_f *cb, void *app_key) {
- Gauge_1_inherit_TYPE_descriptor(td);
- return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
-}
-
-static ber_tlv_tag_t asn_DEF_Gauge_tags_1[] = {
- (ASN_TAG_CLASS_APPLICATION | (2 << 2)),
- (ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
-};
-asn_TYPE_descriptor_t asn_DEF_Gauge = {
- "Gauge",
- "Gauge",
- Gauge_free,
- Gauge_print,
- Gauge_constraint,
- Gauge_decode_ber,
- Gauge_encode_der,
- Gauge_decode_xer,
- Gauge_encode_xer,
- 0, 0, /* No PER support, use "-gen-PER" to enable */
- 0, /* Use generic outmost tag fetcher */
- asn_DEF_Gauge_tags_1,
- sizeof(asn_DEF_Gauge_tags_1)
- /sizeof(asn_DEF_Gauge_tags_1[0]) - 1, /* 1 */
- asn_DEF_Gauge_tags_1, /* Same as above */
- sizeof(asn_DEF_Gauge_tags_1)
- /sizeof(asn_DEF_Gauge_tags_1[0]), /* 2 */
- 0, /* No PER visible constraints */
- 0, 0, /* No members */
- 0 /* No specifics */
-};
-
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1155-SMI"
- * found in "RFC1155-SMI.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#ifndef _Gauge_H_
-#define _Gauge_H_
-
-
-#include <asn_application.h>
-
-/* Including external dependencies */
-#include <INTEGER.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Gauge */
-typedef INTEGER_t Gauge_t;
-
-/* Implementation */
-extern asn_TYPE_descriptor_t asn_DEF_Gauge;
-asn_struct_free_f Gauge_free;
-asn_struct_print_f Gauge_print;
-asn_constr_check_f Gauge_constraint;
-ber_type_decoder_f Gauge_decode_ber;
-der_type_encoder_f Gauge_encode_der;
-xer_type_decoder_f Gauge_decode_xer;
-xer_type_encoder_f Gauge_encode_xer;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _Gauge_H_ */
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1157-SNMP"
- * found in "RFC1157-SNMP.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#include <asn_internal.h>
-
-#include "GetNextRequest-PDU.h"
-
-int
-GetNextRequest_PDU_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
- asn_app_constraint_failed_f *ctfailcb, void *app_key) {
- /* Replace with underlying type checker */
- td->check_constraints = asn_DEF_PDU.check_constraints;
- return td->check_constraints(td, sptr, ctfailcb, app_key);
-}
-
-/*
- * This type is implemented using PDU,
- * so here we adjust the DEF accordingly.
- */
-static void
-GetNextRequest_PDU_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
- td->free_struct = asn_DEF_PDU.free_struct;
- td->print_struct = asn_DEF_PDU.print_struct;
- td->ber_decoder = asn_DEF_PDU.ber_decoder;
- td->der_encoder = asn_DEF_PDU.der_encoder;
- td->xer_decoder = asn_DEF_PDU.xer_decoder;
- td->xer_encoder = asn_DEF_PDU.xer_encoder;
- td->uper_decoder = asn_DEF_PDU.uper_decoder;
- td->uper_encoder = asn_DEF_PDU.uper_encoder;
- if(!td->per_constraints)
- td->per_constraints = asn_DEF_PDU.per_constraints;
- td->elements = asn_DEF_PDU.elements;
- td->elements_count = asn_DEF_PDU.elements_count;
- td->specifics = asn_DEF_PDU.specifics;
-}
-
-void
-GetNextRequest_PDU_free(asn_TYPE_descriptor_t *td,
- void *struct_ptr, int contents_only) {
- GetNextRequest_PDU_1_inherit_TYPE_descriptor(td);
- td->free_struct(td, struct_ptr, contents_only);
-}
-
-int
-GetNextRequest_PDU_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
- int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
- GetNextRequest_PDU_1_inherit_TYPE_descriptor(td);
- return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
-}
-
-asn_dec_rval_t
-GetNextRequest_PDU_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
- void **structure, const void *bufptr, size_t size, int tag_mode) {
- GetNextRequest_PDU_1_inherit_TYPE_descriptor(td);
- return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode);
-}
-
-asn_enc_rval_t
-GetNextRequest_PDU_encode_der(asn_TYPE_descriptor_t *td,
- void *structure, int tag_mode, ber_tlv_tag_t tag,
- asn_app_consume_bytes_f *cb, void *app_key) {
- GetNextRequest_PDU_1_inherit_TYPE_descriptor(td);
- return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
-}
-
-asn_dec_rval_t
-GetNextRequest_PDU_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
- void **structure, const char *opt_mname, const void *bufptr, size_t size) {
- GetNextRequest_PDU_1_inherit_TYPE_descriptor(td);
- return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size);
-}
-
-asn_enc_rval_t
-GetNextRequest_PDU_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
- int ilevel, enum xer_encoder_flags_e flags,
- asn_app_consume_bytes_f *cb, void *app_key) {
- GetNextRequest_PDU_1_inherit_TYPE_descriptor(td);
- return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
-}
-
-static ber_tlv_tag_t asn_DEF_GetNextRequest_PDU_tags_1[] = {
- (ASN_TAG_CLASS_CONTEXT | (1 << 2)),
- (ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
-};
-asn_TYPE_descriptor_t asn_DEF_GetNextRequest_PDU = {
- "GetNextRequest-PDU",
- "GetNextRequest-PDU",
- GetNextRequest_PDU_free,
- GetNextRequest_PDU_print,
- GetNextRequest_PDU_constraint,
- GetNextRequest_PDU_decode_ber,
- GetNextRequest_PDU_encode_der,
- GetNextRequest_PDU_decode_xer,
- GetNextRequest_PDU_encode_xer,
- 0, 0, /* No PER support, use "-gen-PER" to enable */
- 0, /* Use generic outmost tag fetcher */
- asn_DEF_GetNextRequest_PDU_tags_1,
- sizeof(asn_DEF_GetNextRequest_PDU_tags_1)
- /sizeof(asn_DEF_GetNextRequest_PDU_tags_1[0]) - 1, /* 1 */
- asn_DEF_GetNextRequest_PDU_tags_1, /* Same as above */
- sizeof(asn_DEF_GetNextRequest_PDU_tags_1)
- /sizeof(asn_DEF_GetNextRequest_PDU_tags_1[0]), /* 2 */
- 0, /* No PER visible constraints */
- 0, 0, /* Defined elsewhere */
- 0 /* No specifics */
-};
-
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1157-SNMP"
- * found in "RFC1157-SNMP.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#ifndef _GetNextRequest_PDU_H_
-#define _GetNextRequest_PDU_H_
-
-
-#include <asn_application.h>
-
-/* Including external dependencies */
-#include "PDU.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* GetNextRequest-PDU */
-typedef PDU_t GetNextRequest_PDU_t;
-
-/* Implementation */
-extern asn_TYPE_descriptor_t asn_DEF_GetNextRequest_PDU;
-asn_struct_free_f GetNextRequest_PDU_free;
-asn_struct_print_f GetNextRequest_PDU_print;
-asn_constr_check_f GetNextRequest_PDU_constraint;
-ber_type_decoder_f GetNextRequest_PDU_decode_ber;
-der_type_encoder_f GetNextRequest_PDU_encode_der;
-xer_type_decoder_f GetNextRequest_PDU_decode_xer;
-xer_type_encoder_f GetNextRequest_PDU_encode_xer;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _GetNextRequest_PDU_H_ */
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1157-SNMP"
- * found in "RFC1157-SNMP.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#include <asn_internal.h>
-
-#include "GetRequest-PDU.h"
-
-int
-GetRequest_PDU_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
- asn_app_constraint_failed_f *ctfailcb, void *app_key) {
- /* Replace with underlying type checker */
- td->check_constraints = asn_DEF_PDU.check_constraints;
- return td->check_constraints(td, sptr, ctfailcb, app_key);
-}
-
-/*
- * This type is implemented using PDU,
- * so here we adjust the DEF accordingly.
- */
-static void
-GetRequest_PDU_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
- td->free_struct = asn_DEF_PDU.free_struct;
- td->print_struct = asn_DEF_PDU.print_struct;
- td->ber_decoder = asn_DEF_PDU.ber_decoder;
- td->der_encoder = asn_DEF_PDU.der_encoder;
- td->xer_decoder = asn_DEF_PDU.xer_decoder;
- td->xer_encoder = asn_DEF_PDU.xer_encoder;
- td->uper_decoder = asn_DEF_PDU.uper_decoder;
- td->uper_encoder = asn_DEF_PDU.uper_encoder;
- if(!td->per_constraints)
- td->per_constraints = asn_DEF_PDU.per_constraints;
- td->elements = asn_DEF_PDU.elements;
- td->elements_count = asn_DEF_PDU.elements_count;
- td->specifics = asn_DEF_PDU.specifics;
-}
-
-void
-GetRequest_PDU_free(asn_TYPE_descriptor_t *td,
- void *struct_ptr, int contents_only) {
- GetRequest_PDU_1_inherit_TYPE_descriptor(td);
- td->free_struct(td, struct_ptr, contents_only);
-}
-
-int
-GetRequest_PDU_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
- int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
- GetRequest_PDU_1_inherit_TYPE_descriptor(td);
- return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
-}
-
-asn_dec_rval_t
-GetRequest_PDU_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
- void **structure, const void *bufptr, size_t size, int tag_mode) {
- GetRequest_PDU_1_inherit_TYPE_descriptor(td);
- return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode);
-}
-
-asn_enc_rval_t
-GetRequest_PDU_encode_der(asn_TYPE_descriptor_t *td,
- void *structure, int tag_mode, ber_tlv_tag_t tag,
- asn_app_consume_bytes_f *cb, void *app_key) {
- GetRequest_PDU_1_inherit_TYPE_descriptor(td);
- return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
-}
-
-asn_dec_rval_t
-GetRequest_PDU_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
- void **structure, const char *opt_mname, const void *bufptr, size_t size) {
- GetRequest_PDU_1_inherit_TYPE_descriptor(td);
- return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size);
-}
-
-asn_enc_rval_t
-GetRequest_PDU_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
- int ilevel, enum xer_encoder_flags_e flags,
- asn_app_consume_bytes_f *cb, void *app_key) {
- GetRequest_PDU_1_inherit_TYPE_descriptor(td);
- return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
-}
-
-static ber_tlv_tag_t asn_DEF_GetRequest_PDU_tags_1[] = {
- (ASN_TAG_CLASS_CONTEXT | (0 << 2)),
- (ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
-};
-asn_TYPE_descriptor_t asn_DEF_GetRequest_PDU = {
- "GetRequest-PDU",
- "GetRequest-PDU",
- GetRequest_PDU_free,
- GetRequest_PDU_print,
- GetRequest_PDU_constraint,
- GetRequest_PDU_decode_ber,
- GetRequest_PDU_encode_der,
- GetRequest_PDU_decode_xer,
- GetRequest_PDU_encode_xer,
- 0, 0, /* No PER support, use "-gen-PER" to enable */
- 0, /* Use generic outmost tag fetcher */
- asn_DEF_GetRequest_PDU_tags_1,
- sizeof(asn_DEF_GetRequest_PDU_tags_1)
- /sizeof(asn_DEF_GetRequest_PDU_tags_1[0]) - 1, /* 1 */
- asn_DEF_GetRequest_PDU_tags_1, /* Same as above */
- sizeof(asn_DEF_GetRequest_PDU_tags_1)
- /sizeof(asn_DEF_GetRequest_PDU_tags_1[0]), /* 2 */
- 0, /* No PER visible constraints */
- 0, 0, /* Defined elsewhere */
- 0 /* No specifics */
-};
-
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1157-SNMP"
- * found in "RFC1157-SNMP.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#ifndef _GetRequest_PDU_H_
-#define _GetRequest_PDU_H_
-
-
-#include <asn_application.h>
-
-/* Including external dependencies */
-#include "PDU.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* GetRequest-PDU */
-typedef PDU_t GetRequest_PDU_t;
-
-/* Implementation */
-extern asn_TYPE_descriptor_t asn_DEF_GetRequest_PDU;
-asn_struct_free_f GetRequest_PDU_free;
-asn_struct_print_f GetRequest_PDU_print;
-asn_constr_check_f GetRequest_PDU_constraint;
-ber_type_decoder_f GetRequest_PDU_decode_ber;
-der_type_encoder_f GetRequest_PDU_encode_der;
-xer_type_decoder_f GetRequest_PDU_decode_xer;
-xer_type_encoder_f GetRequest_PDU_encode_xer;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _GetRequest_PDU_H_ */
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1157-SNMP"
- * found in "RFC1157-SNMP.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#include <asn_internal.h>
-
-#include "GetResponse-PDU.h"
-
-int
-GetResponse_PDU_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
- asn_app_constraint_failed_f *ctfailcb, void *app_key) {
- /* Replace with underlying type checker */
- td->check_constraints = asn_DEF_PDU.check_constraints;
- return td->check_constraints(td, sptr, ctfailcb, app_key);
-}
-
-/*
- * This type is implemented using PDU,
- * so here we adjust the DEF accordingly.
- */
-static void
-GetResponse_PDU_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
- td->free_struct = asn_DEF_PDU.free_struct;
- td->print_struct = asn_DEF_PDU.print_struct;
- td->ber_decoder = asn_DEF_PDU.ber_decoder;
- td->der_encoder = asn_DEF_PDU.der_encoder;
- td->xer_decoder = asn_DEF_PDU.xer_decoder;
- td->xer_encoder = asn_DEF_PDU.xer_encoder;
- td->uper_decoder = asn_DEF_PDU.uper_decoder;
- td->uper_encoder = asn_DEF_PDU.uper_encoder;
- if(!td->per_constraints)
- td->per_constraints = asn_DEF_PDU.per_constraints;
- td->elements = asn_DEF_PDU.elements;
- td->elements_count = asn_DEF_PDU.elements_count;
- td->specifics = asn_DEF_PDU.specifics;
-}
-
-void
-GetResponse_PDU_free(asn_TYPE_descriptor_t *td,
- void *struct_ptr, int contents_only) {
- GetResponse_PDU_1_inherit_TYPE_descriptor(td);
- td->free_struct(td, struct_ptr, contents_only);
-}
-
-int
-GetResponse_PDU_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
- int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
- GetResponse_PDU_1_inherit_TYPE_descriptor(td);
- return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
-}
-
-asn_dec_rval_t
-GetResponse_PDU_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
- void **structure, const void *bufptr, size_t size, int tag_mode) {
- GetResponse_PDU_1_inherit_TYPE_descriptor(td);
- return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode);
-}
-
-asn_enc_rval_t
-GetResponse_PDU_encode_der(asn_TYPE_descriptor_t *td,
- void *structure, int tag_mode, ber_tlv_tag_t tag,
- asn_app_consume_bytes_f *cb, void *app_key) {
- GetResponse_PDU_1_inherit_TYPE_descriptor(td);
- return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
-}
-
-asn_dec_rval_t
-GetResponse_PDU_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
- void **structure, const char *opt_mname, const void *bufptr, size_t size) {
- GetResponse_PDU_1_inherit_TYPE_descriptor(td);
- return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size);
-}
-
-asn_enc_rval_t
-GetResponse_PDU_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
- int ilevel, enum xer_encoder_flags_e flags,
- asn_app_consume_bytes_f *cb, void *app_key) {
- GetResponse_PDU_1_inherit_TYPE_descriptor(td);
- return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
-}
-
-static ber_tlv_tag_t asn_DEF_GetResponse_PDU_tags_1[] = {
- (ASN_TAG_CLASS_CONTEXT | (2 << 2)),
- (ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
-};
-asn_TYPE_descriptor_t asn_DEF_GetResponse_PDU = {
- "GetResponse-PDU",
- "GetResponse-PDU",
- GetResponse_PDU_free,
- GetResponse_PDU_print,
- GetResponse_PDU_constraint,
- GetResponse_PDU_decode_ber,
- GetResponse_PDU_encode_der,
- GetResponse_PDU_decode_xer,
- GetResponse_PDU_encode_xer,
- 0, 0, /* No PER support, use "-gen-PER" to enable */
- 0, /* Use generic outmost tag fetcher */
- asn_DEF_GetResponse_PDU_tags_1,
- sizeof(asn_DEF_GetResponse_PDU_tags_1)
- /sizeof(asn_DEF_GetResponse_PDU_tags_1[0]) - 1, /* 1 */
- asn_DEF_GetResponse_PDU_tags_1, /* Same as above */
- sizeof(asn_DEF_GetResponse_PDU_tags_1)
- /sizeof(asn_DEF_GetResponse_PDU_tags_1[0]), /* 2 */
- 0, /* No PER visible constraints */
- 0, 0, /* Defined elsewhere */
- 0 /* No specifics */
-};
-
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1157-SNMP"
- * found in "RFC1157-SNMP.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#ifndef _GetResponse_PDU_H_
-#define _GetResponse_PDU_H_
-
-
-#include <asn_application.h>
-
-/* Including external dependencies */
-#include "PDU.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* GetResponse-PDU */
-typedef PDU_t GetResponse_PDU_t;
-
-/* Implementation */
-extern asn_TYPE_descriptor_t asn_DEF_GetResponse_PDU;
-asn_struct_free_f GetResponse_PDU_free;
-asn_struct_print_f GetResponse_PDU_print;
-asn_constr_check_f GetResponse_PDU_constraint;
-ber_type_decoder_f GetResponse_PDU_decode_ber;
-der_type_encoder_f GetResponse_PDU_encode_der;
-xer_type_decoder_f GetResponse_PDU_decode_xer;
-xer_type_encoder_f GetResponse_PDU_encode_xer;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _GetResponse_PDU_H_ */
+++ /dev/null
-/*-
- * Copyright (c) 2003, 2004, 2005, 2006 Lev Walkin <vlm@lionet.info>.
- * All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-#include <asn_internal.h>
-#include <INTEGER.h>
-#include <asn_codecs_prim.h> /* Encoder and decoder of a primitive type */
-#include <errno.h>
-
-/*
- * INTEGER basic type description.
- */
-static ber_tlv_tag_t asn_DEF_INTEGER_tags[] = {
- (ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
-};
-asn_TYPE_descriptor_t asn_DEF_INTEGER = {
- "INTEGER",
- "INTEGER",
- ASN__PRIMITIVE_TYPE_free,
- INTEGER_print,
- asn_generic_no_constraint,
- ber_decode_primitive,
- INTEGER_encode_der,
- INTEGER_decode_xer,
- INTEGER_encode_xer,
- INTEGER_decode_uper, /* Unaligned PER decoder */
- INTEGER_encode_uper, /* Unaligned PER encoder */
- 0, /* Use generic outmost tag fetcher */
- asn_DEF_INTEGER_tags,
- sizeof(asn_DEF_INTEGER_tags) / sizeof(asn_DEF_INTEGER_tags[0]),
- asn_DEF_INTEGER_tags, /* Same as above */
- sizeof(asn_DEF_INTEGER_tags) / sizeof(asn_DEF_INTEGER_tags[0]),
- 0, /* No PER visible constraints */
- 0, 0, /* No members */
- 0 /* No specifics */
-};
-
-/*
- * Encode INTEGER type using DER.
- */
-asn_enc_rval_t
-INTEGER_encode_der(asn_TYPE_descriptor_t *td, void *sptr,
- int tag_mode, ber_tlv_tag_t tag,
- asn_app_consume_bytes_f *cb, void *app_key) {
- INTEGER_t *st = (INTEGER_t *)sptr;
-
- ASN_DEBUG("%s %s as INTEGER (tm=%d)",
- cb?"Encoding":"Estimating", td->name, tag_mode);
-
- /*
- * Canonicalize integer in the buffer.
- * (Remove too long sign extension, remove some first 0x00 bytes)
- */
- if(st->buf) {
- uint8_t *buf = st->buf;
- uint8_t *end1 = buf + st->size - 1;
- int shift;
-
- /* Compute the number of superfluous leading bytes */
- for(; buf < end1; buf++) {
- /*
- * If the contents octets of an integer value encoding
- * consist of more than one octet, then the bits of the
- * first octet and bit 8 of the second octet:
- * a) shall not all be ones; and
- * b) shall not all be zero.
- */
- switch(*buf) {
- case 0x00: if((buf[1] & 0x80) == 0)
- continue;
- break;
- case 0xff: if((buf[1] & 0x80))
- continue;
- break;
- }
- break;
- }
-
- /* Remove leading superfluous bytes from the integer */
- shift = buf - st->buf;
- if(shift) {
- uint8_t *nb = st->buf;
- uint8_t *end;
-
- st->size -= shift; /* New size, minus bad bytes */
- end = nb + st->size;
-
- for(; nb < end; nb++, buf++)
- *nb = *buf;
- }
-
- } /* if(1) */
-
- return der_encode_primitive(td, sptr, tag_mode, tag, cb, app_key);
-}
-
-static const asn_INTEGER_enum_map_t *INTEGER_map_enum2value(asn_INTEGER_specifics_t *specs, const char *lstart, const char *lstop);
-
-/*
- * INTEGER specific human-readable output.
- */
-static ssize_t
-INTEGER__dump(asn_TYPE_descriptor_t *td, const INTEGER_t *st, asn_app_consume_bytes_f *cb, void *app_key, int plainOrXER) {
- asn_INTEGER_specifics_t *specs=(asn_INTEGER_specifics_t *)td->specifics;
- char scratch[32]; /* Enough for 64-bit integer */
- uint8_t *buf = st->buf;
- uint8_t *buf_end = st->buf + st->size;
- signed long accum;
- ssize_t wrote = 0;
- char *p;
- int ret;
-
- /*
- * Advance buf pointer until the start of the value's body.
- * This will make us able to process large integers using simple case,
- * when the actual value is small
- * (0x0000000000abcdef would yield a fine 0x00abcdef)
- */
- /* Skip the insignificant leading bytes */
- for(; buf < buf_end-1; buf++) {
- switch(*buf) {
- case 0x00: if((buf[1] & 0x80) == 0) continue; break;
- case 0xff: if((buf[1] & 0x80) != 0) continue; break;
- }
- break;
- }
-
- /* Simple case: the integer size is small */
- if((size_t)(buf_end - buf) <= sizeof(accum)) {
- const asn_INTEGER_enum_map_t *el;
- size_t scrsize;
- char *scr;
-
- if(buf == buf_end) {
- accum = 0;
- } else {
- accum = (*buf & 0x80) ? -1 : 0;
- for(; buf < buf_end; buf++)
- accum = (accum << 8) | *buf;
- }
-
- el = INTEGER_map_value2enum(specs, accum);
- if(el) {
- scrsize = el->enum_len + 32;
- scr = (char *)alloca(scrsize);
- if(plainOrXER == 0)
- ret = snprintf(scr, scrsize,
- "%ld (%s)", accum, el->enum_name);
- else
- ret = snprintf(scr, scrsize,
- "<%s/>", el->enum_name);
- } else if(plainOrXER && specs && specs->strict_enumeration) {
- ASN_DEBUG("ASN.1 forbids dealing with "
- "unknown value of ENUMERATED type");
- errno = EPERM;
- return -1;
- } else {
- scrsize = sizeof(scratch);
- scr = scratch;
- ret = snprintf(scr, scrsize, "%ld", accum);
- }
- assert(ret > 0 && (size_t)ret < scrsize);
- return (cb(scr, ret, app_key) < 0) ? -1 : ret;
- } else if(plainOrXER && specs && specs->strict_enumeration) {
- /*
- * Here and earlier, we cannot encode the ENUMERATED values
- * if there is no corresponding identifier.
- */
- ASN_DEBUG("ASN.1 forbids dealing with "
- "unknown value of ENUMERATED type");
- errno = EPERM;
- return -1;
- }
-
- /* Output in the long xx:yy:zz... format */
- /* TODO: replace with generic algorithm (Knuth TAOCP Vol 2, 4.3.1) */
- for(p = scratch; buf < buf_end; buf++) {
- static const char *h2c = "0123456789ABCDEF";
- if((p - scratch) >= (ssize_t)(sizeof(scratch) - 4)) {
- /* Flush buffer */
- if(cb(scratch, p - scratch, app_key) < 0)
- return -1;
- wrote += p - scratch;
- p = scratch;
- }
- *p++ = h2c[*buf >> 4];
- *p++ = h2c[*buf & 0x0F];
- *p++ = 0x3a; /* ":" */
- }
- if(p != scratch)
- p--; /* Remove the last ":" */
-
- wrote += p - scratch;
- return (cb(scratch, p - scratch, app_key) < 0) ? -1 : wrote;
-}
-
-/*
- * INTEGER specific human-readable output.
- */
-int
-INTEGER_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
- asn_app_consume_bytes_f *cb, void *app_key) {
- const INTEGER_t *st = (const INTEGER_t *)sptr;
- ssize_t ret;
-
- (void)td;
- (void)ilevel;
-
- if(!st || !st->buf)
- ret = cb("<absent>", 8, app_key);
- else
- ret = INTEGER__dump(td, st, cb, app_key, 0);
-
- return (ret < 0) ? -1 : 0;
-}
-
-struct e2v_key {
- const char *start;
- const char *stop;
- asn_INTEGER_enum_map_t *vemap;
- unsigned int *evmap;
-};
-static int
-INTEGER__compar_enum2value(const void *kp, const void *am) {
- const struct e2v_key *key = (const struct e2v_key *)kp;
- const asn_INTEGER_enum_map_t *el = (const asn_INTEGER_enum_map_t *)am;
- const char *ptr, *end, *name;
-
- /* Remap the element (sort by different criterion) */
- el = key->vemap + key->evmap[el - key->vemap];
-
- /* Compare strings */
- for(ptr = key->start, end = key->stop, name = el->enum_name;
- ptr < end; ptr++, name++) {
- if(*ptr != *name)
- return *(const unsigned char *)ptr
- - *(const unsigned char *)name;
- }
- return name[0] ? -1 : 0;
-}
-
-static const asn_INTEGER_enum_map_t *
-INTEGER_map_enum2value(asn_INTEGER_specifics_t *specs, const char *lstart, const char *lstop) {
- asn_INTEGER_enum_map_t *el_found;
- int count = specs ? specs->map_count : 0;
- struct e2v_key key;
- const char *lp;
-
- if(!count) return NULL;
-
- /* Guaranteed: assert(lstart < lstop); */
- /* Figure out the tag name */
- for(lstart++, lp = lstart; lp < lstop; lp++) {
- switch(*lp) {
- case 9: case 10: case 11: case 12: case 13: case 32: /* WSP */
- case 0x2f: /* '/' */ case 0x3e: /* '>' */
- break;
- default:
- continue;
- }
- break;
- }
- if(lp == lstop) return NULL; /* No tag found */
- lstop = lp;
-
- key.start = lstart;
- key.stop = lstop;
- key.vemap = specs->value2enum;
- key.evmap = specs->enum2value;
- el_found = (asn_INTEGER_enum_map_t *)bsearch(&key,
- specs->value2enum, count, sizeof(specs->value2enum[0]),
- INTEGER__compar_enum2value);
- if(el_found) {
- /* Remap enum2value into value2enum */
- el_found = key.vemap + key.evmap[el_found - key.vemap];
- }
- return el_found;
-}
-
-static int
-INTEGER__compar_value2enum(const void *kp, const void *am) {
- long a = *(const long *)kp;
- const asn_INTEGER_enum_map_t *el = (const asn_INTEGER_enum_map_t *)am;
- long b = el->nat_value;
- if(a < b) return -1;
- else if(a == b) return 0;
- else return 1;
-}
-
-const asn_INTEGER_enum_map_t *
-INTEGER_map_value2enum(asn_INTEGER_specifics_t *specs, long value) {
- int count = specs ? specs->map_count : 0;
- if(!count) return 0;
- return (asn_INTEGER_enum_map_t *)bsearch(&value, specs->value2enum,
- count, sizeof(specs->value2enum[0]),
- INTEGER__compar_value2enum);
-}
-
-static int
-INTEGER_st_prealloc(INTEGER_t *st, int min_size) {
- void *p = MALLOC(min_size + 1);
- if(p) {
- void *b = st->buf;
- st->size = 0;
- st->buf = p;
- FREEMEM(b);
- return 0;
- } else {
- return -1;
- }
-}
-
-/*
- * Decode the chunk of XML text encoding INTEGER.
- */
-static enum xer_pbd_rval
-INTEGER__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chunk_buf, size_t chunk_size) {
- INTEGER_t *st = (INTEGER_t *)sptr;
- long sign = 1;
- long value;
- const char *lp;
- const char *lstart = (const char *)chunk_buf;
- const char *lstop = lstart + chunk_size;
- enum {
- ST_SKIPSPACE,
- ST_SKIPSPHEX,
- ST_WAITDIGITS,
- ST_DIGITS,
- ST_HEXDIGIT1,
- ST_HEXDIGIT2,
- ST_HEXCOLON,
- ST_EXTRASTUFF
- } state = ST_SKIPSPACE;
-
- if(chunk_size)
- ASN_DEBUG("INTEGER body %d 0x%2x..0x%2x",
- chunk_size, *lstart, lstop[-1]);
-
- /*
- * We may have received a tag here. It will be processed inline.
- * Use strtoul()-like code and serialize the result.
- */
- for(value = 0, lp = lstart; lp < lstop; lp++) {
- int lv = *lp;
- switch(lv) {
- case 0x09: case 0x0a: case 0x0d: case 0x20:
- switch(state) {
- case ST_SKIPSPACE:
- case ST_SKIPSPHEX:
- continue;
- case ST_HEXCOLON:
- if(xer_is_whitespace(lp, lstop - lp)) {
- lp = lstop - 1;
- continue;
- }
- break;
- default:
- break;
- }
- break;
- case 0x2d: /* '-' */
- if(state == ST_SKIPSPACE) {
- sign = -1;
- state = ST_WAITDIGITS;
- continue;
- }
- break;
- case 0x2b: /* '+' */
- if(state == ST_SKIPSPACE) {
- state = ST_WAITDIGITS;
- continue;
- }
- break;
- case 0x30: case 0x31: case 0x32: case 0x33: case 0x34:
- case 0x35: case 0x36: case 0x37: case 0x38: case 0x39:
- switch(state) {
- case ST_DIGITS: break;
- case ST_SKIPSPHEX: /* Fall through */
- case ST_HEXDIGIT1:
- value = (lv - 0x30) << 4;
- state = ST_HEXDIGIT2;
- continue;
- case ST_HEXDIGIT2:
- value += (lv - 0x30);
- state = ST_HEXCOLON;
- st->buf[st->size++] = value;
- continue;
- case ST_HEXCOLON:
- return XPBD_BROKEN_ENCODING;
- default:
- state = ST_DIGITS;
- break;
- }
-
- {
- long new_value = value * 10;
-
- if(new_value / 10 != value)
- /* Overflow */
- return XPBD_DECODER_LIMIT;
-
- value = new_value + (lv - 0x30);
- /* Check for two's complement overflow */
- if(value < 0) {
- /* Check whether it is a LONG_MIN */
- if(sign == -1
- && (unsigned long)value
- == ~((unsigned long)-1 >> 1)) {
- sign = 1;
- } else {
- /* Overflow */
- return XPBD_DECODER_LIMIT;
- }
- }
- }
- continue;
- case 0x3c: /* '<' */
- if(state == ST_SKIPSPACE) {
- const asn_INTEGER_enum_map_t *el;
- el = INTEGER_map_enum2value(
- (asn_INTEGER_specifics_t *)
- td->specifics, lstart, lstop);
- if(el) {
- ASN_DEBUG("Found \"%s\" => %ld",
- el->enum_name, el->nat_value);
- state = ST_DIGITS;
- value = el->nat_value;
- lp = lstop - 1;
- continue;
- }
- ASN_DEBUG("Unknown identifier for INTEGER");
- }
- return XPBD_BROKEN_ENCODING;
- case 0x3a: /* ':' */
- if(state == ST_HEXCOLON) {
- /* This colon is expected */
- state = ST_HEXDIGIT1;
- continue;
- } else if(state == ST_DIGITS) {
- /* The colon here means that we have
- * decoded the first two hexadecimal
- * places as a decimal value.
- * Switch decoding mode. */
- ASN_DEBUG("INTEGER re-evaluate as hex form");
- if(INTEGER_st_prealloc(st, (chunk_size/3) + 1))
- return XPBD_SYSTEM_FAILURE;
- state = ST_SKIPSPHEX;
- lp = lstart - 1;
- continue;
- } else {
- ASN_DEBUG("state %d at %d", state, lp - lstart);
- break;
- }
- /* [A-Fa-f] */
- case 0x41:case 0x42:case 0x43:case 0x44:case 0x45:case 0x46:
- case 0x61:case 0x62:case 0x63:case 0x64:case 0x65:case 0x66:
- switch(state) {
- case ST_SKIPSPHEX:
- case ST_SKIPSPACE: /* Fall through */
- case ST_HEXDIGIT1:
- value = lv - ((lv < 0x61) ? 0x41 : 0x61);
- value += 10;
- value <<= 4;
- state = ST_HEXDIGIT2;
- continue;
- case ST_HEXDIGIT2:
- value += lv - ((lv < 0x61) ? 0x41 : 0x61);
- value += 10;
- st->buf[st->size++] = value;
- state = ST_HEXCOLON;
- continue;
- case ST_DIGITS:
- ASN_DEBUG("INTEGER re-evaluate as hex form");
- if(INTEGER_st_prealloc(st, (chunk_size/3) + 1))
- return XPBD_SYSTEM_FAILURE;
- state = ST_SKIPSPHEX;
- lp = lstart - 1;
- continue;
- default:
- break;
- }
- break;
- }
-
- /* Found extra non-numeric stuff */
- ASN_DEBUG("Found non-numeric 0x%2x at %d",
- lv, lp - lstart);
- state = ST_EXTRASTUFF;
- break;
- }
-
- switch(state) {
- case ST_DIGITS:
- /* Everything is cool */
- break;
- case ST_HEXCOLON:
- st->buf[st->size] = 0; /* Just in case termination */
- return XPBD_BODY_CONSUMED;
- case ST_HEXDIGIT1:
- case ST_HEXDIGIT2:
- case ST_SKIPSPHEX:
- return XPBD_BROKEN_ENCODING;
- default:
- if(xer_is_whitespace(lp, lstop - lp)) {
- if(state != ST_EXTRASTUFF)
- return XPBD_NOT_BODY_IGNORE;
- break;
- } else {
- ASN_DEBUG("INTEGER: No useful digits (state %d)",
- state);
- return XPBD_BROKEN_ENCODING; /* No digits */
- }
- break;
- }
-
- value *= sign; /* Change sign, if needed */
-
- if(asn_long2INTEGER(st, value))
- return XPBD_SYSTEM_FAILURE;
-
- return XPBD_BODY_CONSUMED;
-}
-
-asn_dec_rval_t
-INTEGER_decode_xer(asn_codec_ctx_t *opt_codec_ctx,
- asn_TYPE_descriptor_t *td, void **sptr, const char *opt_mname,
- const void *buf_ptr, size_t size) {
-
- return xer_decode_primitive(opt_codec_ctx, td,
- sptr, sizeof(INTEGER_t), opt_mname,
- buf_ptr, size, INTEGER__xer_body_decode);
-}
-
-asn_enc_rval_t
-INTEGER_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
- int ilevel, enum xer_encoder_flags_e flags,
- asn_app_consume_bytes_f *cb, void *app_key) {
- const INTEGER_t *st = (const INTEGER_t *)sptr;
- asn_enc_rval_t er;
-
- (void)ilevel;
- (void)flags;
-
- if(!st || !st->buf)
- _ASN_ENCODE_FAILED;
-
- er.encoded = INTEGER__dump(td, st, cb, app_key, 1);
- if(er.encoded < 0) _ASN_ENCODE_FAILED;
-
- _ASN_ENCODED_OK(er);
-}
-
-asn_dec_rval_t
-INTEGER_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
- asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
- asn_dec_rval_t rval = { RC_OK, 0 };
- INTEGER_t *st = (INTEGER_t *)*sptr;
- asn_per_constraint_t *ct;
- int repeat;
-
- (void)opt_codec_ctx;
-
- if(!st) {
- st = (INTEGER_t *)(*sptr = CALLOC(1, sizeof(*st)));
- if(!st) _ASN_DECODE_FAILED;
- }
-
- if(!constraints) constraints = td->per_constraints;
- ct = constraints ? &constraints->value : 0;
-
- if(ct && ct->flags & APC_EXTENSIBLE) {
- int inext = per_get_few_bits(pd, 1);
- if(inext < 0) _ASN_DECODE_STARVED;
- if(inext) ct = 0;
- }
-
- FREEMEM(st->buf);
- if(ct) {
- if(ct->flags & APC_SEMI_CONSTRAINED) {
- st->buf = (uint8_t *)CALLOC(1, 2);
- if(!st->buf) _ASN_DECODE_FAILED;
- st->size = 1;
- } else if(ct->flags & APC_CONSTRAINED && ct->range_bits >= 0) {
- size_t size = (ct->range_bits + 7) >> 3;
- st->buf = (uint8_t *)MALLOC(1 + size + 1);
- if(!st->buf) _ASN_DECODE_FAILED;
- st->size = size;
- } else {
- st->size = 0;
- }
- } else {
- st->size = 0;
- }
-
- /* X.691, #12.2.2 */
- if(ct && ct->flags != APC_UNCONSTRAINED) {
- /* #10.5.6 */
- ASN_DEBUG("Integer with range %d bits", ct->range_bits);
- if(ct->range_bits >= 0) {
- long value = per_get_few_bits(pd, ct->range_bits);
- if(value < 0) _ASN_DECODE_STARVED;
- ASN_DEBUG("Got value %ld + low %ld",
- value, ct->lower_bound);
- value += ct->lower_bound;
- if(asn_long2INTEGER(st, value))
- _ASN_DECODE_FAILED;
- return rval;
- }
- } else {
- ASN_DEBUG("Decoding unconstrained integer %s", td->name);
- }
-
- /* X.691, #12.2.3, #12.2.4 */
- do {
- ssize_t len;
- void *p;
- int ret;
-
- /* Get the PER length */
- len = uper_get_length(pd, -1, &repeat);
- if(len < 0) _ASN_DECODE_STARVED;
-
- p = REALLOC(st->buf, st->size + len + 1);
- if(!p) _ASN_DECODE_FAILED;
- st->buf = (uint8_t *)p;
-
- ret = per_get_many_bits(pd, &st->buf[st->size], 0, 8 * len);
- if(ret < 0) _ASN_DECODE_STARVED;
- st->size += len;
- } while(repeat);
- st->buf[st->size] = 0; /* JIC */
-
- /* #12.2.3 */
- if(ct && ct->lower_bound) {
- /*
- * TODO: replace by in-place arithmetics.
- */
- long value;
- if(asn_INTEGER2long(st, &value))
- _ASN_DECODE_FAILED;
- if(asn_long2INTEGER(st, value + ct->lower_bound))
- _ASN_DECODE_FAILED;
- }
-
- return rval;
-}
-
-asn_enc_rval_t
-INTEGER_encode_uper(asn_TYPE_descriptor_t *td,
- asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
- asn_enc_rval_t er;
- INTEGER_t *st = (INTEGER_t *)sptr;
- const uint8_t *buf;
- const uint8_t *end;
- asn_per_constraint_t *ct;
- long value = 0;
-
- if(!st || st->size == 0) _ASN_ENCODE_FAILED;
-
- if(!constraints) constraints = td->per_constraints;
- ct = constraints ? &constraints->value : 0;
-
- er.encoded = 0;
-
- if(ct) {
- int inext = 0;
- if(asn_INTEGER2long(st, &value))
- _ASN_ENCODE_FAILED;
- /* Check proper range */
- if(ct->flags & APC_SEMI_CONSTRAINED) {
- if(value < ct->lower_bound)
- inext = 1;
- } else if(ct->range_bits >= 0) {
- if(value < ct->lower_bound
- || value > ct->upper_bound)
- inext = 1;
- }
- ASN_DEBUG("Value %ld (%02x/%d) lb %ld ub %ld %s",
- value, st->buf[0], st->size,
- ct->lower_bound, ct->upper_bound,
- inext ? "ext" : "fix");
- if(ct->flags & APC_EXTENSIBLE) {
- if(per_put_few_bits(po, inext, 1))
- _ASN_ENCODE_FAILED;
- if(inext) ct = 0;
- } else if(inext) {
- _ASN_ENCODE_FAILED;
- }
- }
-
-
- /* X.691, #12.2.2 */
- if(ct && ct->range_bits >= 0) {
- /* #10.5.6 */
- ASN_DEBUG("Encoding integer with range %d bits",
- ct->range_bits);
- if(per_put_few_bits(po, value - ct->lower_bound,
- ct->range_bits))
- _ASN_ENCODE_FAILED;
- _ASN_ENCODED_OK(er);
- }
-
- if(ct && ct->lower_bound) {
- ASN_DEBUG("Adjust lower bound to %ld", ct->lower_bound);
- /* TODO: adjust lower bound */
- _ASN_ENCODE_FAILED;
- }
-
- for(buf = st->buf, end = st->buf + st->size; buf < end;) {
- ssize_t mayEncode = uper_put_length(po, end - buf);
- if(mayEncode < 0)
- _ASN_ENCODE_FAILED;
- if(per_put_many_bits(po, buf, 8 * mayEncode))
- _ASN_ENCODE_FAILED;
- buf += mayEncode;
- }
-
- _ASN_ENCODED_OK(er);
-}
-
-int
-asn_INTEGER2long(const INTEGER_t *iptr, long *lptr) {
- uint8_t *b, *end;
- size_t size;
- long l;
-
- /* Sanity checking */
- if(!iptr || !iptr->buf || !lptr) {
- errno = EINVAL;
- return -1;
- }
-
- /* Cache the begin/end of the buffer */
- b = iptr->buf; /* Start of the INTEGER buffer */
- size = iptr->size;
- end = b + size; /* Where to stop */
-
- if(size > sizeof(long)) {
- uint8_t *end1 = end - 1;
- /*
- * Slightly more advanced processing,
- * able to >sizeof(long) bytes,
- * when the actual value is small
- * (0x0000000000abcdef would yield a fine 0x00abcdef)
- */
- /* Skip out the insignificant leading bytes */
- for(; b < end1; b++) {
- switch(*b) {
- case 0x00: if((b[1] & 0x80) == 0) continue; break;
- case 0xff: if((b[1] & 0x80) != 0) continue; break;
- }
- break;
- }
-
- size = end - b;
- if(size > sizeof(long)) {
- /* Still cannot fit the long */
- errno = ERANGE;
- return -1;
- }
- }
-
- /* Shortcut processing of a corner case */
- if(end == b) {
- *lptr = 0;
- return 0;
- }
-
- /* Perform the sign initialization */
- /* Actually l = -(*b >> 7); gains nothing, yet unreadable! */
- if((*b >> 7)) l = -1; else l = 0;
-
- /* Conversion engine */
- for(; b < end; b++)
- l = (l << 8) | *b;
-
- *lptr = l;
- return 0;
-}
-
-int
-asn_long2INTEGER(INTEGER_t *st, long value) {
- uint8_t *buf, *bp;
- uint8_t *p;
- uint8_t *pstart;
- uint8_t *pend1;
- int littleEndian = 1; /* Run-time detection */
- int add;
-
- if(!st) {
- errno = EINVAL;
- return -1;
- }
-
- buf = (uint8_t *)MALLOC(sizeof(value));
- if(!buf) return -1;
-
- if(*(char *)&littleEndian) {
- pstart = (uint8_t *)&value + sizeof(value) - 1;
- pend1 = (uint8_t *)&value;
- add = -1;
- } else {
- pstart = (uint8_t *)&value;
- pend1 = pstart + sizeof(value) - 1;
- add = 1;
- }
-
- /*
- * If the contents octet consists of more than one octet,
- * then bits of the first octet and bit 8 of the second octet:
- * a) shall not all be ones; and
- * b) shall not all be zero.
- */
- for(p = pstart; p != pend1; p += add) {
- switch(*p) {
- case 0x00: if((*(p+add) & 0x80) == 0)
- continue;
- break;
- case 0xff: if((*(p+add) & 0x80))
- continue;
- break;
- }
- break;
- }
- /* Copy the integer body */
- for(pstart = p, bp = buf, pend1 += add; p != pend1; p += add)
- *bp++ = *p;
-
- if(st->buf) FREEMEM(st->buf);
- st->buf = buf;
- st->size = bp - buf;
-
- return 0;
-}
+++ /dev/null
-/*-
- * Copyright (c) 2003, 2005 Lev Walkin <vlm@lionet.info>. All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-#ifndef _INTEGER_H_
-#define _INTEGER_H_
-
-#include <asn_application.h>
-#include <asn_codecs_prim.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef ASN__PRIMITIVE_TYPE_t INTEGER_t;
-
-extern asn_TYPE_descriptor_t asn_DEF_INTEGER;
-
-/* Map with <tag> to integer value association */
-typedef struct asn_INTEGER_enum_map_s {
- long nat_value; /* associated native integer value */
- size_t enum_len; /* strlen("tag") */
- const char *enum_name; /* "tag" */
-} asn_INTEGER_enum_map_t;
-
-/* This type describes an enumeration for INTEGER and ENUMERATED types */
-typedef struct asn_INTEGER_specifics_s {
- asn_INTEGER_enum_map_t *value2enum; /* N -> "tag"; sorted by N */
- unsigned int *enum2value; /* "tag" => N; sorted by tag */
- int map_count; /* Elements in either map */
- int extension; /* This map is extensible */
- int strict_enumeration; /* Enumeration set is fixed */
-} asn_INTEGER_specifics_t;
-
-asn_struct_print_f INTEGER_print;
-ber_type_decoder_f INTEGER_decode_ber;
-der_type_encoder_f INTEGER_encode_der;
-xer_type_decoder_f INTEGER_decode_xer;
-xer_type_encoder_f INTEGER_encode_xer;
-per_type_decoder_f INTEGER_decode_uper;
-per_type_encoder_f INTEGER_encode_uper;
-
-/***********************************
- * Some handy conversion routines. *
- ***********************************/
-
-/*
- * Returns 0 if it was possible to convert, -1 otherwise.
- * -1/EINVAL: Mandatory argument missing
- * -1/ERANGE: Value encoded is out of range for long representation
- * -1/ENOMEM: Memory allocation failed (in asn_long2INTEGER()).
- */
-int asn_INTEGER2long(const INTEGER_t *i, long *l);
-int asn_long2INTEGER(INTEGER_t *i, long l);
-
-/*
- * Convert the integer value into the corresponding enumeration map entry.
- */
-const asn_INTEGER_enum_map_t *INTEGER_map_value2enum(asn_INTEGER_specifics_t *specs, long value);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _INTEGER_H_ */
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1213-MIB"
- * found in "RFC1213-MIB.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#include <asn_internal.h>
-
-#include "IfEntry.h"
-
-static asn_TYPE_member_t asn_MBR_IfEntry_1[] = {
- { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifIndex),
- (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
- 0,
- &asn_DEF_INTEGER,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "ifIndex"
- },
- { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifDescr),
- (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)),
- 0,
- &asn_DEF_DisplayString,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "ifDescr"
- },
- { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifType),
- (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
- 0,
- &asn_DEF_INTEGER,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "ifType"
- },
- { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifMtu),
- (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
- 0,
- &asn_DEF_INTEGER,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "ifMtu"
- },
- { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifSpeed),
- (ASN_TAG_CLASS_APPLICATION | (2 << 2)),
- 0,
- &asn_DEF_Gauge,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "ifSpeed"
- },
- { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifPhysAddress),
- (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)),
- 0,
- &asn_DEF_PhysAddress,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "ifPhysAddress"
- },
- { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifAdminStatus),
- (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
- 0,
- &asn_DEF_INTEGER,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "ifAdminStatus"
- },
- { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifOperStatus),
- (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
- 0,
- &asn_DEF_INTEGER,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "ifOperStatus"
- },
- { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifLastChange),
- (ASN_TAG_CLASS_APPLICATION | (3 << 2)),
- 0,
- &asn_DEF_TimeTicks,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "ifLastChange"
- },
- { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifInOctets),
- (ASN_TAG_CLASS_APPLICATION | (1 << 2)),
- 0,
- &asn_DEF_Counter,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "ifInOctets"
- },
- { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifInUcastPkts),
- (ASN_TAG_CLASS_APPLICATION | (1 << 2)),
- 0,
- &asn_DEF_Counter,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "ifInUcastPkts"
- },
- { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifInNUcastPkts),
- (ASN_TAG_CLASS_APPLICATION | (1 << 2)),
- 0,
- &asn_DEF_Counter,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "ifInNUcastPkts"
- },
- { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifInDiscards),
- (ASN_TAG_CLASS_APPLICATION | (1 << 2)),
- 0,
- &asn_DEF_Counter,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "ifInDiscards"
- },
- { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifInErrors),
- (ASN_TAG_CLASS_APPLICATION | (1 << 2)),
- 0,
- &asn_DEF_Counter,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "ifInErrors"
- },
- { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifInUnknownProtos),
- (ASN_TAG_CLASS_APPLICATION | (1 << 2)),
- 0,
- &asn_DEF_Counter,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "ifInUnknownProtos"
- },
- { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifOutOctets),
- (ASN_TAG_CLASS_APPLICATION | (1 << 2)),
- 0,
- &asn_DEF_Counter,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "ifOutOctets"
- },
- { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifOutUcastPkts),
- (ASN_TAG_CLASS_APPLICATION | (1 << 2)),
- 0,
- &asn_DEF_Counter,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "ifOutUcastPkts"
- },
- { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifOutNUcastPkts),
- (ASN_TAG_CLASS_APPLICATION | (1 << 2)),
- 0,
- &asn_DEF_Counter,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "ifOutNUcastPkts"
- },
- { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifOutDiscards),
- (ASN_TAG_CLASS_APPLICATION | (1 << 2)),
- 0,
- &asn_DEF_Counter,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "ifOutDiscards"
- },
- { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifOutErrors),
- (ASN_TAG_CLASS_APPLICATION | (1 << 2)),
- 0,
- &asn_DEF_Counter,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "ifOutErrors"
- },
- { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifOutQLen),
- (ASN_TAG_CLASS_APPLICATION | (2 << 2)),
- 0,
- &asn_DEF_Gauge,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "ifOutQLen"
- },
- { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifSpecific),
- (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)),
- 0,
- &asn_DEF_OBJECT_IDENTIFIER,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "ifSpecific"
- },
-};
-static ber_tlv_tag_t asn_DEF_IfEntry_tags_1[] = {
- (ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
-};
-static asn_TYPE_tag2member_t asn_MAP_IfEntry_tag2el_1[] = {
- { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 4 }, /* ifIndex at 78 */
- { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 2, -1, 3 }, /* ifType at 83 */
- { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 3, -2, 2 }, /* ifMtu at 85 */
- { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 6, -3, 1 }, /* ifAdminStatus at 91 */
- { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 7, -4, 0 }, /* ifOperStatus at 93 */
- { (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 1, 0, 1 }, /* ifDescr at 81 */
- { (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 5, -1, 0 }, /* ifPhysAddress at 89 */
- { (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)), 21, 0, 0 }, /* ifSpecific at 121 */
- { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 9, 0, 10 }, /* ifInOctets at 97 */
- { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 10, -1, 9 }, /* ifInUcastPkts at 99 */
- { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 11, -2, 8 }, /* ifInNUcastPkts at 101 */
- { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 12, -3, 7 }, /* ifInDiscards at 103 */
- { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 13, -4, 6 }, /* ifInErrors at 105 */
- { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 14, -5, 5 }, /* ifInUnknownProtos at 107 */
- { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 15, -6, 4 }, /* ifOutOctets at 109 */
- { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 16, -7, 3 }, /* ifOutUcastPkts at 111 */
- { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 17, -8, 2 }, /* ifOutNUcastPkts at 113 */
- { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 18, -9, 1 }, /* ifOutDiscards at 115 */
- { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 19, -10, 0 }, /* ifOutErrors at 117 */
- { (ASN_TAG_CLASS_APPLICATION | (2 << 2)), 4, 0, 1 }, /* ifSpeed at 87 */
- { (ASN_TAG_CLASS_APPLICATION | (2 << 2)), 20, -1, 0 }, /* ifOutQLen at 119 */
- { (ASN_TAG_CLASS_APPLICATION | (3 << 2)), 8, 0, 0 } /* ifLastChange at 95 */
-};
-static asn_SEQUENCE_specifics_t asn_SPC_IfEntry_specs_1 = {
- sizeof(struct IfEntry),
- offsetof(struct IfEntry, _asn_ctx),
- asn_MAP_IfEntry_tag2el_1,
- 22, /* Count of tags in the map */
- 0, 0, 0, /* Optional elements (not needed) */
- -1, /* Start extensions */
- -1 /* Stop extensions */
-};
-asn_TYPE_descriptor_t asn_DEF_IfEntry = {
- "IfEntry",
- "IfEntry",
- SEQUENCE_free,
- SEQUENCE_print,
- SEQUENCE_constraint,
- SEQUENCE_decode_ber,
- SEQUENCE_encode_der,
- SEQUENCE_decode_xer,
- SEQUENCE_encode_xer,
- 0, 0, /* No PER support, use "-gen-PER" to enable */
- 0, /* Use generic outmost tag fetcher */
- asn_DEF_IfEntry_tags_1,
- sizeof(asn_DEF_IfEntry_tags_1)
- /sizeof(asn_DEF_IfEntry_tags_1[0]), /* 1 */
- asn_DEF_IfEntry_tags_1, /* Same as above */
- sizeof(asn_DEF_IfEntry_tags_1)
- /sizeof(asn_DEF_IfEntry_tags_1[0]), /* 1 */
- 0, /* No PER visible constraints */
- asn_MBR_IfEntry_1,
- 22, /* Elements count */
- &asn_SPC_IfEntry_specs_1 /* Additional specs */
-};
-
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1213-MIB"
- * found in "RFC1213-MIB.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#ifndef _IfEntry_H_
-#define _IfEntry_H_
-
-
-#include <asn_application.h>
-
-/* Including external dependencies */
-#include <INTEGER.h>
-#include "DisplayString.h"
-#include "Gauge.h"
-#include "PhysAddress.h"
-#include "TimeTicks.h"
-#include "Counter.h"
-#include <OBJECT_IDENTIFIER.h>
-#include <constr_SEQUENCE.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* IfEntry */
-typedef struct IfEntry {
- INTEGER_t ifIndex;
- DisplayString_t ifDescr;
- INTEGER_t ifType;
- INTEGER_t ifMtu;
- Gauge_t ifSpeed;
- PhysAddress_t ifPhysAddress;
- INTEGER_t ifAdminStatus;
- INTEGER_t ifOperStatus;
- TimeTicks_t ifLastChange;
- Counter_t ifInOctets;
- Counter_t ifInUcastPkts;
- Counter_t ifInNUcastPkts;
- Counter_t ifInDiscards;
- Counter_t ifInErrors;
- Counter_t ifInUnknownProtos;
- Counter_t ifOutOctets;
- Counter_t ifOutUcastPkts;
- Counter_t ifOutNUcastPkts;
- Counter_t ifOutDiscards;
- Counter_t ifOutErrors;
- Gauge_t ifOutQLen;
- OBJECT_IDENTIFIER_t ifSpecific;
-
- /* Context for parsing across buffer boundaries */
- asn_struct_ctx_t _asn_ctx;
-} IfEntry_t;
-
-/* Implementation */
-extern asn_TYPE_descriptor_t asn_DEF_IfEntry;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _IfEntry_H_ */
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1213-MIB"
- * found in "RFC1213-MIB.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#include <asn_internal.h>
-
-#include "IpAddrEntry.h"
-
-static int
-memb_ipAdEntReasmMaxSize_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr,
- asn_app_constraint_failed_f *ctfailcb, void *app_key) {
- long value;
-
- if(!sptr) {
- _ASN_CTFAIL(app_key, td, sptr,
- "%s: value not given (%s:%d)",
- td->name, __FILE__, __LINE__);
- return -1;
- }
-
- value = *(const long *)sptr;
-
- if((value >= 0 && value <= 65535)) {
- /* Constraint check succeeded */
- return 0;
- } else {
- _ASN_CTFAIL(app_key, td, sptr,
- "%s: constraint failed (%s:%d)",
- td->name, __FILE__, __LINE__);
- return -1;
- }
-}
-
-static asn_TYPE_member_t asn_MBR_IpAddrEntry_1[] = {
- { ATF_NOFLAGS, 0, offsetof(struct IpAddrEntry, ipAdEntAddr),
- (ASN_TAG_CLASS_APPLICATION | (0 << 2)),
- 0,
- &asn_DEF_IpAddress,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "ipAdEntAddr"
- },
- { ATF_NOFLAGS, 0, offsetof(struct IpAddrEntry, ipAdEntIfIndex),
- (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
- 0,
- &asn_DEF_INTEGER,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "ipAdEntIfIndex"
- },
- { ATF_NOFLAGS, 0, offsetof(struct IpAddrEntry, ipAdEntNetMask),
- (ASN_TAG_CLASS_APPLICATION | (0 << 2)),
- 0,
- &asn_DEF_IpAddress,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "ipAdEntNetMask"
- },
- { ATF_NOFLAGS, 0, offsetof(struct IpAddrEntry, ipAdEntBcastAddr),
- (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
- 0,
- &asn_DEF_INTEGER,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "ipAdEntBcastAddr"
- },
- { ATF_NOFLAGS, 0, offsetof(struct IpAddrEntry, ipAdEntReasmMaxSize),
- (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
- 0,
- &asn_DEF_NativeInteger,
- memb_ipAdEntReasmMaxSize_constraint_1,
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "ipAdEntReasmMaxSize"
- },
-};
-static ber_tlv_tag_t asn_DEF_IpAddrEntry_tags_1[] = {
- (ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
-};
-static asn_TYPE_tag2member_t asn_MAP_IpAddrEntry_tag2el_1[] = {
- { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 1, 0, 2 }, /* ipAdEntIfIndex at 177 */
- { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 3, -1, 1 }, /* ipAdEntBcastAddr at 181 */
- { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 4, -2, 0 }, /* ipAdEntReasmMaxSize at 183 */
- { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 0, 0, 1 }, /* ipAdEntAddr at 175 */
- { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 2, -1, 0 } /* ipAdEntNetMask at 179 */
-};
-static asn_SEQUENCE_specifics_t asn_SPC_IpAddrEntry_specs_1 = {
- sizeof(struct IpAddrEntry),
- offsetof(struct IpAddrEntry, _asn_ctx),
- asn_MAP_IpAddrEntry_tag2el_1,
- 5, /* Count of tags in the map */
- 0, 0, 0, /* Optional elements (not needed) */
- -1, /* Start extensions */
- -1 /* Stop extensions */
-};
-asn_TYPE_descriptor_t asn_DEF_IpAddrEntry = {
- "IpAddrEntry",
- "IpAddrEntry",
- SEQUENCE_free,
- SEQUENCE_print,
- SEQUENCE_constraint,
- SEQUENCE_decode_ber,
- SEQUENCE_encode_der,
- SEQUENCE_decode_xer,
- SEQUENCE_encode_xer,
- 0, 0, /* No PER support, use "-gen-PER" to enable */
- 0, /* Use generic outmost tag fetcher */
- asn_DEF_IpAddrEntry_tags_1,
- sizeof(asn_DEF_IpAddrEntry_tags_1)
- /sizeof(asn_DEF_IpAddrEntry_tags_1[0]), /* 1 */
- asn_DEF_IpAddrEntry_tags_1, /* Same as above */
- sizeof(asn_DEF_IpAddrEntry_tags_1)
- /sizeof(asn_DEF_IpAddrEntry_tags_1[0]), /* 1 */
- 0, /* No PER visible constraints */
- asn_MBR_IpAddrEntry_1,
- 5, /* Elements count */
- &asn_SPC_IpAddrEntry_specs_1 /* Additional specs */
-};
-
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1213-MIB"
- * found in "RFC1213-MIB.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#ifndef _IpAddrEntry_H_
-#define _IpAddrEntry_H_
-
-
-#include <asn_application.h>
-
-/* Including external dependencies */
-#include "IpAddress.h"
-#include <INTEGER.h>
-#include <NativeInteger.h>
-#include <constr_SEQUENCE.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* IpAddrEntry */
-typedef struct IpAddrEntry {
- IpAddress_t ipAdEntAddr;
- INTEGER_t ipAdEntIfIndex;
- IpAddress_t ipAdEntNetMask;
- INTEGER_t ipAdEntBcastAddr;
- long ipAdEntReasmMaxSize;
-
- /* Context for parsing across buffer boundaries */
- asn_struct_ctx_t _asn_ctx;
-} IpAddrEntry_t;
-
-/* Implementation */
-extern asn_TYPE_descriptor_t asn_DEF_IpAddrEntry;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _IpAddrEntry_H_ */
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1155-SMI"
- * found in "RFC1155-SMI.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#include <asn_internal.h>
-
-#include "IpAddress.h"
-
-int
-IpAddress_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
- asn_app_constraint_failed_f *ctfailcb, void *app_key) {
- const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr;
- size_t size;
-
- if(!sptr) {
- _ASN_CTFAIL(app_key, td, sptr,
- "%s: value not given (%s:%d)",
- td->name, __FILE__, __LINE__);
- return -1;
- }
-
- size = st->size;
-
- if((size == 4)) {
- /* Constraint check succeeded */
- return 0;
- } else {
- _ASN_CTFAIL(app_key, td, sptr,
- "%s: constraint failed (%s:%d)",
- td->name, __FILE__, __LINE__);
- return -1;
- }
-}
-
-/*
- * This type is implemented using OCTET_STRING,
- * so here we adjust the DEF accordingly.
- */
-static void
-IpAddress_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
- td->free_struct = asn_DEF_OCTET_STRING.free_struct;
- td->print_struct = asn_DEF_OCTET_STRING.print_struct;
- td->ber_decoder = asn_DEF_OCTET_STRING.ber_decoder;
- td->der_encoder = asn_DEF_OCTET_STRING.der_encoder;
- td->xer_decoder = asn_DEF_OCTET_STRING.xer_decoder;
- td->xer_encoder = asn_DEF_OCTET_STRING.xer_encoder;
- td->uper_decoder = asn_DEF_OCTET_STRING.uper_decoder;
- td->uper_encoder = asn_DEF_OCTET_STRING.uper_encoder;
- if(!td->per_constraints)
- td->per_constraints = asn_DEF_OCTET_STRING.per_constraints;
- td->elements = asn_DEF_OCTET_STRING.elements;
- td->elements_count = asn_DEF_OCTET_STRING.elements_count;
- td->specifics = asn_DEF_OCTET_STRING.specifics;
-}
-
-void
-IpAddress_free(asn_TYPE_descriptor_t *td,
- void *struct_ptr, int contents_only) {
- IpAddress_1_inherit_TYPE_descriptor(td);
- td->free_struct(td, struct_ptr, contents_only);
-}
-
-int
-IpAddress_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
- int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
- IpAddress_1_inherit_TYPE_descriptor(td);
- return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
-}
-
-asn_dec_rval_t
-IpAddress_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
- void **structure, const void *bufptr, size_t size, int tag_mode) {
- IpAddress_1_inherit_TYPE_descriptor(td);
- return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode);
-}
-
-asn_enc_rval_t
-IpAddress_encode_der(asn_TYPE_descriptor_t *td,
- void *structure, int tag_mode, ber_tlv_tag_t tag,
- asn_app_consume_bytes_f *cb, void *app_key) {
- IpAddress_1_inherit_TYPE_descriptor(td);
- return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
-}
-
-asn_dec_rval_t
-IpAddress_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
- void **structure, const char *opt_mname, const void *bufptr, size_t size) {
- IpAddress_1_inherit_TYPE_descriptor(td);
- return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size);
-}
-
-asn_enc_rval_t
-IpAddress_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
- int ilevel, enum xer_encoder_flags_e flags,
- asn_app_consume_bytes_f *cb, void *app_key) {
- IpAddress_1_inherit_TYPE_descriptor(td);
- return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
-}
-
-static ber_tlv_tag_t asn_DEF_IpAddress_tags_1[] = {
- (ASN_TAG_CLASS_APPLICATION | (0 << 2)),
- (ASN_TAG_CLASS_UNIVERSAL | (4 << 2))
-};
-asn_TYPE_descriptor_t asn_DEF_IpAddress = {
- "IpAddress",
- "IpAddress",
- IpAddress_free,
- IpAddress_print,
- IpAddress_constraint,
- IpAddress_decode_ber,
- IpAddress_encode_der,
- IpAddress_decode_xer,
- IpAddress_encode_xer,
- 0, 0, /* No PER support, use "-gen-PER" to enable */
- 0, /* Use generic outmost tag fetcher */
- asn_DEF_IpAddress_tags_1,
- sizeof(asn_DEF_IpAddress_tags_1)
- /sizeof(asn_DEF_IpAddress_tags_1[0]) - 1, /* 1 */
- asn_DEF_IpAddress_tags_1, /* Same as above */
- sizeof(asn_DEF_IpAddress_tags_1)
- /sizeof(asn_DEF_IpAddress_tags_1[0]), /* 2 */
- 0, /* No PER visible constraints */
- 0, 0, /* No members */
- 0 /* No specifics */
-};
-
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1155-SMI"
- * found in "RFC1155-SMI.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#ifndef _IpAddress_H_
-#define _IpAddress_H_
-
-
-#include <asn_application.h>
-
-/* Including external dependencies */
-#include <OCTET_STRING.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* IpAddress */
-typedef OCTET_STRING_t IpAddress_t;
-
-/* Implementation */
-extern asn_TYPE_descriptor_t asn_DEF_IpAddress;
-asn_struct_free_f IpAddress_free;
-asn_struct_print_f IpAddress_print;
-asn_constr_check_f IpAddress_constraint;
-ber_type_decoder_f IpAddress_decode_ber;
-der_type_encoder_f IpAddress_encode_der;
-xer_type_decoder_f IpAddress_decode_xer;
-xer_type_encoder_f IpAddress_encode_xer;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _IpAddress_H_ */
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1213-MIB"
- * found in "RFC1213-MIB.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#include <asn_internal.h>
-
-#include "IpNetToMediaEntry.h"
-
-static asn_TYPE_member_t asn_MBR_IpNetToMediaEntry_1[] = {
- { ATF_NOFLAGS, 0, offsetof(struct IpNetToMediaEntry, ipNetToMediaIfIndex),
- (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
- 0,
- &asn_DEF_INTEGER,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "ipNetToMediaIfIndex"
- },
- { ATF_NOFLAGS, 0, offsetof(struct IpNetToMediaEntry, ipNetToMediaPhysAddress),
- (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)),
- 0,
- &asn_DEF_PhysAddress,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "ipNetToMediaPhysAddress"
- },
- { ATF_NOFLAGS, 0, offsetof(struct IpNetToMediaEntry, ipNetToMediaNetAddress),
- (ASN_TAG_CLASS_APPLICATION | (0 << 2)),
- 0,
- &asn_DEF_IpAddress,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "ipNetToMediaNetAddress"
- },
- { ATF_NOFLAGS, 0, offsetof(struct IpNetToMediaEntry, ipNetToMediaType),
- (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
- 0,
- &asn_DEF_INTEGER,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "ipNetToMediaType"
- },
-};
-static ber_tlv_tag_t asn_DEF_IpNetToMediaEntry_tags_1[] = {
- (ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
-};
-static asn_TYPE_tag2member_t asn_MAP_IpNetToMediaEntry_tag2el_1[] = {
- { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 1 }, /* ipNetToMediaIfIndex at 222 */
- { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 3, -1, 0 }, /* ipNetToMediaType at 229 */
- { (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 1, 0, 0 }, /* ipNetToMediaPhysAddress at 224 */
- { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 2, 0, 0 } /* ipNetToMediaNetAddress at 226 */
-};
-static asn_SEQUENCE_specifics_t asn_SPC_IpNetToMediaEntry_specs_1 = {
- sizeof(struct IpNetToMediaEntry),
- offsetof(struct IpNetToMediaEntry, _asn_ctx),
- asn_MAP_IpNetToMediaEntry_tag2el_1,
- 4, /* Count of tags in the map */
- 0, 0, 0, /* Optional elements (not needed) */
- -1, /* Start extensions */
- -1 /* Stop extensions */
-};
-asn_TYPE_descriptor_t asn_DEF_IpNetToMediaEntry = {
- "IpNetToMediaEntry",
- "IpNetToMediaEntry",
- SEQUENCE_free,
- SEQUENCE_print,
- SEQUENCE_constraint,
- SEQUENCE_decode_ber,
- SEQUENCE_encode_der,
- SEQUENCE_decode_xer,
- SEQUENCE_encode_xer,
- 0, 0, /* No PER support, use "-gen-PER" to enable */
- 0, /* Use generic outmost tag fetcher */
- asn_DEF_IpNetToMediaEntry_tags_1,
- sizeof(asn_DEF_IpNetToMediaEntry_tags_1)
- /sizeof(asn_DEF_IpNetToMediaEntry_tags_1[0]), /* 1 */
- asn_DEF_IpNetToMediaEntry_tags_1, /* Same as above */
- sizeof(asn_DEF_IpNetToMediaEntry_tags_1)
- /sizeof(asn_DEF_IpNetToMediaEntry_tags_1[0]), /* 1 */
- 0, /* No PER visible constraints */
- asn_MBR_IpNetToMediaEntry_1,
- 4, /* Elements count */
- &asn_SPC_IpNetToMediaEntry_specs_1 /* Additional specs */
-};
-
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1213-MIB"
- * found in "RFC1213-MIB.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#ifndef _IpNetToMediaEntry_H_
-#define _IpNetToMediaEntry_H_
-
-
-#include <asn_application.h>
-
-/* Including external dependencies */
-#include <INTEGER.h>
-#include "PhysAddress.h"
-#include "IpAddress.h"
-#include <constr_SEQUENCE.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* IpNetToMediaEntry */
-typedef struct IpNetToMediaEntry {
- INTEGER_t ipNetToMediaIfIndex;
- PhysAddress_t ipNetToMediaPhysAddress;
- IpAddress_t ipNetToMediaNetAddress;
- INTEGER_t ipNetToMediaType;
-
- /* Context for parsing across buffer boundaries */
- asn_struct_ctx_t _asn_ctx;
-} IpNetToMediaEntry_t;
-
-/* Implementation */
-extern asn_TYPE_descriptor_t asn_DEF_IpNetToMediaEntry;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _IpNetToMediaEntry_H_ */
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1213-MIB"
- * found in "RFC1213-MIB.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#include <asn_internal.h>
-
-#include "IpRouteEntry.h"
-
-static asn_TYPE_member_t asn_MBR_IpRouteEntry_1[] = {
- { ATF_NOFLAGS, 0, offsetof(struct IpRouteEntry, ipRouteDest),
- (ASN_TAG_CLASS_APPLICATION | (0 << 2)),
- 0,
- &asn_DEF_IpAddress,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "ipRouteDest"
- },
- { ATF_NOFLAGS, 0, offsetof(struct IpRouteEntry, ipRouteIfIndex),
- (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
- 0,
- &asn_DEF_INTEGER,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "ipRouteIfIndex"
- },
- { ATF_NOFLAGS, 0, offsetof(struct IpRouteEntry, ipRouteMetric1),
- (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
- 0,
- &asn_DEF_INTEGER,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "ipRouteMetric1"
- },
- { ATF_NOFLAGS, 0, offsetof(struct IpRouteEntry, ipRouteMetric2),
- (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
- 0,
- &asn_DEF_INTEGER,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "ipRouteMetric2"
- },
- { ATF_NOFLAGS, 0, offsetof(struct IpRouteEntry, ipRouteMetric3),
- (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
- 0,
- &asn_DEF_INTEGER,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "ipRouteMetric3"
- },
- { ATF_NOFLAGS, 0, offsetof(struct IpRouteEntry, ipRouteMetric4),
- (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
- 0,
- &asn_DEF_INTEGER,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "ipRouteMetric4"
- },
- { ATF_NOFLAGS, 0, offsetof(struct IpRouteEntry, ipRouteNextHop),
- (ASN_TAG_CLASS_APPLICATION | (0 << 2)),
- 0,
- &asn_DEF_IpAddress,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "ipRouteNextHop"
- },
- { ATF_NOFLAGS, 0, offsetof(struct IpRouteEntry, ipRouteType),
- (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
- 0,
- &asn_DEF_INTEGER,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "ipRouteType"
- },
- { ATF_NOFLAGS, 0, offsetof(struct IpRouteEntry, ipRouteProto),
- (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
- 0,
- &asn_DEF_INTEGER,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "ipRouteProto"
- },
- { ATF_NOFLAGS, 0, offsetof(struct IpRouteEntry, ipRouteAge),
- (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
- 0,
- &asn_DEF_INTEGER,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "ipRouteAge"
- },
- { ATF_NOFLAGS, 0, offsetof(struct IpRouteEntry, ipRouteMask),
- (ASN_TAG_CLASS_APPLICATION | (0 << 2)),
- 0,
- &asn_DEF_IpAddress,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "ipRouteMask"
- },
- { ATF_NOFLAGS, 0, offsetof(struct IpRouteEntry, ipRouteMetric5),
- (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
- 0,
- &asn_DEF_INTEGER,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "ipRouteMetric5"
- },
- { ATF_NOFLAGS, 0, offsetof(struct IpRouteEntry, ipRouteInfo),
- (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)),
- 0,
- &asn_DEF_OBJECT_IDENTIFIER,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "ipRouteInfo"
- },
-};
-static ber_tlv_tag_t asn_DEF_IpRouteEntry_tags_1[] = {
- (ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
-};
-static asn_TYPE_tag2member_t asn_MAP_IpRouteEntry_tag2el_1[] = {
- { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 1, 0, 8 }, /* ipRouteIfIndex at 192 */
- { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 2, -1, 7 }, /* ipRouteMetric1 at 194 */
- { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 3, -2, 6 }, /* ipRouteMetric2 at 196 */
- { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 4, -3, 5 }, /* ipRouteMetric3 at 198 */
- { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 5, -4, 4 }, /* ipRouteMetric4 at 200 */
- { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 7, -5, 3 }, /* ipRouteType at 204 */
- { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 8, -6, 2 }, /* ipRouteProto at 206 */
- { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 9, -7, 1 }, /* ipRouteAge at 208 */
- { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 11, -8, 0 }, /* ipRouteMetric5 at 212 */
- { (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)), 12, 0, 0 }, /* ipRouteInfo at 215 */
- { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 0, 0, 2 }, /* ipRouteDest at 190 */
- { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 6, -1, 1 }, /* ipRouteNextHop at 202 */
- { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 10, -2, 0 } /* ipRouteMask at 210 */
-};
-static asn_SEQUENCE_specifics_t asn_SPC_IpRouteEntry_specs_1 = {
- sizeof(struct IpRouteEntry),
- offsetof(struct IpRouteEntry, _asn_ctx),
- asn_MAP_IpRouteEntry_tag2el_1,
- 13, /* Count of tags in the map */
- 0, 0, 0, /* Optional elements (not needed) */
- -1, /* Start extensions */
- -1 /* Stop extensions */
-};
-asn_TYPE_descriptor_t asn_DEF_IpRouteEntry = {
- "IpRouteEntry",
- "IpRouteEntry",
- SEQUENCE_free,
- SEQUENCE_print,
- SEQUENCE_constraint,
- SEQUENCE_decode_ber,
- SEQUENCE_encode_der,
- SEQUENCE_decode_xer,
- SEQUENCE_encode_xer,
- 0, 0, /* No PER support, use "-gen-PER" to enable */
- 0, /* Use generic outmost tag fetcher */
- asn_DEF_IpRouteEntry_tags_1,
- sizeof(asn_DEF_IpRouteEntry_tags_1)
- /sizeof(asn_DEF_IpRouteEntry_tags_1[0]), /* 1 */
- asn_DEF_IpRouteEntry_tags_1, /* Same as above */
- sizeof(asn_DEF_IpRouteEntry_tags_1)
- /sizeof(asn_DEF_IpRouteEntry_tags_1[0]), /* 1 */
- 0, /* No PER visible constraints */
- asn_MBR_IpRouteEntry_1,
- 13, /* Elements count */
- &asn_SPC_IpRouteEntry_specs_1 /* Additional specs */
-};
-
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1213-MIB"
- * found in "RFC1213-MIB.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#ifndef _IpRouteEntry_H_
-#define _IpRouteEntry_H_
-
-
-#include <asn_application.h>
-
-/* Including external dependencies */
-#include "IpAddress.h"
-#include <INTEGER.h>
-#include <OBJECT_IDENTIFIER.h>
-#include <constr_SEQUENCE.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* IpRouteEntry */
-typedef struct IpRouteEntry {
- IpAddress_t ipRouteDest;
- INTEGER_t ipRouteIfIndex;
- INTEGER_t ipRouteMetric1;
- INTEGER_t ipRouteMetric2;
- INTEGER_t ipRouteMetric3;
- INTEGER_t ipRouteMetric4;
- IpAddress_t ipRouteNextHop;
- INTEGER_t ipRouteType;
- INTEGER_t ipRouteProto;
- INTEGER_t ipRouteAge;
- IpAddress_t ipRouteMask;
- INTEGER_t ipRouteMetric5;
- OBJECT_IDENTIFIER_t ipRouteInfo;
-
- /* Context for parsing across buffer boundaries */
- asn_struct_ctx_t _asn_ctx;
-} IpRouteEntry_t;
-
-/* Implementation */
-extern asn_TYPE_descriptor_t asn_DEF_IpRouteEntry;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _IpRouteEntry_H_ */
+++ /dev/null
-ASN1_SOURCES = RFC1213-MIB.asn1 \
- RFC1155-SMI.asn1 \
- RFC1157-SNMP.asn1 \
- SMUX.asn1
-
-asn1: $(ASN1_SOURCES)
- asn1c -fskeletons-copy -fcompound-names $^
- rm Makefile.am.sample
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1157-SNMP"
- * found in "RFC1157-SNMP.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#include <asn_internal.h>
-
-#include "Message.h"
-
-static asn_TYPE_member_t asn_MBR_Message_1[] = {
- { ATF_NOFLAGS, 0, offsetof(struct Message, version),
- (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
- 0,
- &asn_DEF_INTEGER,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "version"
- },
- { ATF_NOFLAGS, 0, offsetof(struct Message, community),
- (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)),
- 0,
- &asn_DEF_OCTET_STRING,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "community"
- },
- { ATF_OPEN_TYPE | ATF_NOFLAGS, 0, offsetof(struct Message, data),
- -1 /* Ambiguous tag (ANY?) */,
- 0,
- &asn_DEF_ANY,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "data"
- },
-};
-static ber_tlv_tag_t asn_DEF_Message_tags_1[] = {
- (ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
-};
-static asn_TYPE_tag2member_t asn_MAP_Message_tag2el_1[] = {
- { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 0 }, /* version at 18 */
- { (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 1, 0, 0 } /* community at 22 */
-};
-static asn_SEQUENCE_specifics_t asn_SPC_Message_specs_1 = {
- sizeof(struct Message),
- offsetof(struct Message, _asn_ctx),
- asn_MAP_Message_tag2el_1,
- 2, /* Count of tags in the map */
- 0, 0, 0, /* Optional elements (not needed) */
- -1, /* Start extensions */
- -1 /* Stop extensions */
-};
-asn_TYPE_descriptor_t asn_DEF_Message = {
- "Message",
- "Message",
- SEQUENCE_free,
- SEQUENCE_print,
- SEQUENCE_constraint,
- SEQUENCE_decode_ber,
- SEQUENCE_encode_der,
- SEQUENCE_decode_xer,
- SEQUENCE_encode_xer,
- 0, 0, /* No PER support, use "-gen-PER" to enable */
- 0, /* Use generic outmost tag fetcher */
- asn_DEF_Message_tags_1,
- sizeof(asn_DEF_Message_tags_1)
- /sizeof(asn_DEF_Message_tags_1[0]), /* 1 */
- asn_DEF_Message_tags_1, /* Same as above */
- sizeof(asn_DEF_Message_tags_1)
- /sizeof(asn_DEF_Message_tags_1[0]), /* 1 */
- 0, /* No PER visible constraints */
- asn_MBR_Message_1,
- 3, /* Elements count */
- &asn_SPC_Message_specs_1 /* Additional specs */
-};
-
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1157-SNMP"
- * found in "RFC1157-SNMP.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#ifndef _Message_H_
-#define _Message_H_
-
-
-#include <asn_application.h>
-
-/* Including external dependencies */
-#include <INTEGER.h>
-#include <OCTET_STRING.h>
-#include <ANY.h>
-#include <constr_SEQUENCE.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Dependencies */
-typedef enum Message__version {
- Message__version_version_1 = 0
-} e_Message__version;
-
-/* Message */
-typedef struct Message {
- INTEGER_t version;
- OCTET_STRING_t community;
- ANY_t data;
-
- /* Context for parsing across buffer boundaries */
- asn_struct_ctx_t _asn_ctx;
-} Message_t;
-
-/* Implementation */
-extern asn_TYPE_descriptor_t asn_DEF_Message;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _Message_H_ */
+++ /dev/null
-/*-
- * Copyright (c) 2003, 2005 Lev Walkin <vlm@lionet.info>. All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-#include <asn_internal.h>
-#include <asn_codecs_prim.h>
-#include <NULL.h>
-#include <BOOLEAN.h> /* Implemented in terms of BOOLEAN type */
-
-/*
- * NULL basic type description.
- */
-static ber_tlv_tag_t asn_DEF_NULL_tags[] = {
- (ASN_TAG_CLASS_UNIVERSAL | (5 << 2))
-};
-asn_TYPE_descriptor_t asn_DEF_NULL = {
- "NULL",
- "NULL",
- BOOLEAN_free,
- NULL_print,
- asn_generic_no_constraint,
- BOOLEAN_decode_ber, /* Implemented in terms of BOOLEAN */
- NULL_encode_der, /* Special handling of DER encoding */
- NULL_decode_xer,
- NULL_encode_xer,
- NULL_decode_uper, /* Unaligned PER decoder */
- NULL_encode_uper, /* Unaligned PER encoder */
- 0, /* Use generic outmost tag fetcher */
- asn_DEF_NULL_tags,
- sizeof(asn_DEF_NULL_tags) / sizeof(asn_DEF_NULL_tags[0]),
- asn_DEF_NULL_tags, /* Same as above */
- sizeof(asn_DEF_NULL_tags) / sizeof(asn_DEF_NULL_tags[0]),
- 0, /* No PER visible constraints */
- 0, 0, /* No members */
- 0 /* No specifics */
-};
-
-asn_enc_rval_t
-NULL_encode_der(asn_TYPE_descriptor_t *td, void *ptr,
- int tag_mode, ber_tlv_tag_t tag,
- asn_app_consume_bytes_f *cb, void *app_key) {
- asn_enc_rval_t erval;
-
- erval.encoded = der_write_tags(td, 0, tag_mode, 0, tag, cb, app_key);
- if(erval.encoded == -1) {
- erval.failed_type = td;
- erval.structure_ptr = ptr;
- }
-
- _ASN_ENCODED_OK(erval);
-}
-
-asn_enc_rval_t
-NULL_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
- int ilevel, enum xer_encoder_flags_e flags,
- asn_app_consume_bytes_f *cb, void *app_key) {
- asn_enc_rval_t er;
-
- (void)td;
- (void)sptr;
- (void)ilevel;
- (void)flags;
- (void)cb;
- (void)app_key;
-
- /* XMLNullValue is empty */
- er.encoded = 0;
- _ASN_ENCODED_OK(er);
-}
-
-
-static enum xer_pbd_rval
-NULL__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chunk_buf, size_t chunk_size) {
- (void)td;
- (void)sptr;
-
- if(xer_is_whitespace(chunk_buf, chunk_size))
- return XPBD_BODY_CONSUMED;
- else
- return XPBD_BROKEN_ENCODING;
-}
-
-asn_dec_rval_t
-NULL_decode_xer(asn_codec_ctx_t *opt_codec_ctx,
- asn_TYPE_descriptor_t *td, void **sptr, const char *opt_mname,
- const void *buf_ptr, size_t size) {
-
- return xer_decode_primitive(opt_codec_ctx, td,
- sptr, sizeof(NULL_t), opt_mname, buf_ptr, size,
- NULL__xer_body_decode);
-}
-
-int
-NULL_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
- asn_app_consume_bytes_f *cb, void *app_key) {
-
- (void)td; /* Unused argument */
- (void)ilevel; /* Unused argument */
-
- if(sptr) {
- return (cb("<present>", 9, app_key) < 0) ? -1 : 0;
- } else {
- return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
- }
-}
-
-asn_dec_rval_t
-NULL_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
- asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
- asn_dec_rval_t rv;
-
- (void)opt_codec_ctx;
- (void)td;
- (void)constraints;
- (void)pd;
-
- if(!*sptr) {
- *sptr = MALLOC(sizeof(NULL_t));
- if(*sptr) {
- *(NULL_t *)*sptr = 0;
- } else {
- _ASN_DECODE_FAILED;
- }
- }
-
- /*
- * NULL type does not have content octets.
- */
-
- rv.code = RC_OK;
- rv.consumed = 0;
- return rv;
-}
-
-asn_enc_rval_t
-NULL_encode_uper(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints,
- void *sptr, asn_per_outp_t *po) {
- asn_enc_rval_t er;
-
- (void)td;
- (void)constraints;
- (void)sptr;
- (void)po;
-
- er.encoded = 0;
- _ASN_ENCODED_OK(er);
-}
+++ /dev/null
-/*-
- * Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-#ifndef ASN_TYPE_NULL_H
-#define ASN_TYPE_NULL_H
-
-#include <asn_application.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * The value of the NULL type is meaningless: see BOOLEAN if you want to
- * carry true/false semantics.
- */
-typedef int NULL_t;
-
-extern asn_TYPE_descriptor_t asn_DEF_NULL;
-
-asn_struct_print_f NULL_print;
-der_type_encoder_f NULL_encode_der;
-xer_type_decoder_f NULL_decode_xer;
-xer_type_encoder_f NULL_encode_xer;
-per_type_decoder_f NULL_decode_uper;
-per_type_encoder_f NULL_encode_uper;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* NULL_H */
+++ /dev/null
-/*-
- * Copyright (c) 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-/*
- * Read the NativeInteger.h for the explanation wrt. differences between
- * INTEGER and NativeInteger.
- * Basically, both are decoders and encoders of ASN.1 INTEGER type, but this
- * implementation deals with the standard (machine-specific) representation
- * of them instead of using the platform-independent buffer.
- */
-#include <asn_internal.h>
-#include <NativeEnumerated.h>
-
-/*
- * NativeEnumerated basic type description.
- */
-static ber_tlv_tag_t asn_DEF_NativeEnumerated_tags[] = {
- (ASN_TAG_CLASS_UNIVERSAL | (10 << 2))
-};
-asn_TYPE_descriptor_t asn_DEF_NativeEnumerated = {
- "ENUMERATED", /* The ASN.1 type is still ENUMERATED */
- "ENUMERATED",
- NativeInteger_free,
- NativeInteger_print,
- asn_generic_no_constraint,
- NativeInteger_decode_ber,
- NativeInteger_encode_der,
- NativeInteger_decode_xer,
- NativeEnumerated_encode_xer,
- NativeEnumerated_decode_uper,
- NativeEnumerated_encode_uper,
- 0, /* Use generic outmost tag fetcher */
- asn_DEF_NativeEnumerated_tags,
- sizeof(asn_DEF_NativeEnumerated_tags) / sizeof(asn_DEF_NativeEnumerated_tags[0]),
- asn_DEF_NativeEnumerated_tags, /* Same as above */
- sizeof(asn_DEF_NativeEnumerated_tags) / sizeof(asn_DEF_NativeEnumerated_tags[0]),
- 0, /* No PER visible constraints */
- 0, 0, /* No members */
- 0 /* No specifics */
-};
-
-asn_enc_rval_t
-NativeEnumerated_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
- int ilevel, enum xer_encoder_flags_e flags,
- asn_app_consume_bytes_f *cb, void *app_key) {
- asn_INTEGER_specifics_t *specs=(asn_INTEGER_specifics_t *)td->specifics;
- asn_enc_rval_t er;
- const long *native = (const long *)sptr;
- const asn_INTEGER_enum_map_t *el;
-
- (void)ilevel;
- (void)flags;
-
- if(!native) _ASN_ENCODE_FAILED;
-
- el = INTEGER_map_value2enum(specs, *native);
- if(el) {
- size_t srcsize = el->enum_len + 5;
- char *src = (char *)alloca(srcsize);
-
- er.encoded = snprintf(src, srcsize, "<%s/>", el->enum_name);
- assert(er.encoded > 0 && (size_t)er.encoded < srcsize);
- if(cb(src, er.encoded, app_key) < 0) _ASN_ENCODE_FAILED;
- _ASN_ENCODED_OK(er);
- } else {
- ASN_DEBUG("ASN.1 forbids dealing with "
- "unknown value of ENUMERATED type");
- _ASN_ENCODE_FAILED;
- }
-}
-
-asn_dec_rval_t
-NativeEnumerated_decode_uper(asn_codec_ctx_t *opt_codec_ctx,
- asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints,
- void **sptr, asn_per_data_t *pd) {
- asn_INTEGER_specifics_t *specs = (asn_INTEGER_specifics_t *)td->specifics;
- asn_dec_rval_t rval = { RC_OK, 0 };
- long *native = (long *)*sptr;
- asn_per_constraint_t *ct;
- long value;
-
- (void)opt_codec_ctx;
-
- if(constraints) ct = &constraints->value;
- else if(td->per_constraints) ct = &td->per_constraints->value;
- else _ASN_DECODE_FAILED; /* Mandatory! */
- if(!specs) _ASN_DECODE_FAILED;
-
- if(!native) {
- native = (long *)(*sptr = CALLOC(1, sizeof(*native)));
- if(!native) _ASN_DECODE_FAILED;
- }
-
- ASN_DEBUG("Decoding %s as NativeEnumerated", td->name);
-
- if(ct->flags & APC_EXTENSIBLE) {
- int inext = per_get_few_bits(pd, 1);
- if(inext < 0) _ASN_DECODE_STARVED;
- if(inext) ct = 0;
- }
-
- if(ct && ct->range_bits >= 0) {
- value = per_get_few_bits(pd, ct->range_bits);
- if(value < 0) _ASN_DECODE_STARVED;
- if(value >= (specs->extension
- ? specs->extension - 1 : specs->map_count))
- _ASN_DECODE_FAILED;
- } else {
- if(!specs->extension)
- _ASN_DECODE_FAILED;
- /*
- * X.691, #10.6: normally small non-negative whole number;
- */
- value = uper_get_nsnnwn(pd);
- if(value < 0) _ASN_DECODE_STARVED;
- value += specs->extension - 1;
- if(value >= specs->map_count)
- _ASN_DECODE_FAILED;
- }
-
- *native = specs->value2enum[value].nat_value;
- ASN_DEBUG("Decoded %s = %ld", td->name, *native);
-
- return rval;
-}
-
-static int
-NativeEnumerated__compar_value2enum(const void *ap, const void *bp) {
- const asn_INTEGER_enum_map_t *a = ap;
- const asn_INTEGER_enum_map_t *b = bp;
- if(a->nat_value == b->nat_value)
- return 0;
- if(a->nat_value < b->nat_value)
- return -1;
- return 1;
-}
-
-asn_enc_rval_t
-NativeEnumerated_encode_uper(asn_TYPE_descriptor_t *td,
- asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
- asn_INTEGER_specifics_t *specs = (asn_INTEGER_specifics_t *)td->specifics;
- asn_enc_rval_t er;
- long native, value;
- asn_per_constraint_t *ct;
- int inext = 0;
- asn_INTEGER_enum_map_t key;
- asn_INTEGER_enum_map_t *kf;
-
- if(!sptr) _ASN_ENCODE_FAILED;
- if(!specs) _ASN_ENCODE_FAILED;
-
- if(constraints) ct = &constraints->value;
- else if(td->per_constraints) ct = &td->per_constraints->value;
- else _ASN_ENCODE_FAILED; /* Mandatory! */
-
- ASN_DEBUG("Encoding %s as NativeEnumerated", td->name);
-
- er.encoded = 0;
-
- native = *(long *)sptr;
- if(native < 0) _ASN_ENCODE_FAILED;
-
- key.nat_value = native;
- kf = bsearch(&key, specs->value2enum, specs->map_count,
- sizeof(key), NativeEnumerated__compar_value2enum);
- if(!kf) {
- ASN_DEBUG("No element corresponds to %ld", native);
- _ASN_ENCODE_FAILED;
- }
- value = kf - specs->value2enum;
-
- if(ct->range_bits >= 0) {
- int cmpWith = specs->extension
- ? specs->extension - 1 : specs->map_count;
- if(value >= cmpWith)
- inext = 1;
- }
- if(ct->flags & APC_EXTENSIBLE) {
- if(per_put_few_bits(po, inext, 0))
- _ASN_ENCODE_FAILED;
- ct = 0;
- } else if(inext) {
- _ASN_ENCODE_FAILED;
- }
-
- if(ct && ct->range_bits >= 0) {
- if(per_put_few_bits(po, value, ct->range_bits))
- _ASN_ENCODE_FAILED;
- _ASN_ENCODED_OK(er);
- }
-
- if(!specs->extension)
- _ASN_ENCODE_FAILED;
-
- /*
- * X.691, #10.6: normally small non-negative whole number;
- */
- if(uper_put_nsnnwn(po, value - (specs->extension - 1)))
- _ASN_ENCODE_FAILED;
-
- _ASN_ENCODED_OK(er);
-}
-
+++ /dev/null
-/*-
- * Copyright (c) 2004, 2005, 2006 Lev Walkin <vlm@lionet.info>.
- * All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-/*
- * This type differs from the standard ENUMERATED in that it is modelled using
- * the fixed machine type (long, int, short), so it can hold only values of
- * limited length. There is no type (i.e., NativeEnumerated_t, any integer type
- * will do).
- * This type may be used when integer range is limited by subtype constraints.
- */
-#ifndef _NativeEnumerated_H_
-#define _NativeEnumerated_H_
-
-#include <NativeInteger.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern asn_TYPE_descriptor_t asn_DEF_NativeEnumerated;
-
-xer_type_encoder_f NativeEnumerated_encode_xer;
-per_type_decoder_f NativeEnumerated_decode_uper;
-per_type_encoder_f NativeEnumerated_encode_uper;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _NativeEnumerated_H_ */
+++ /dev/null
-/*-
- * Copyright (c) 2004, 2005, 2006 Lev Walkin <vlm@lionet.info>.
- * All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-/*
- * Read the NativeInteger.h for the explanation wrt. differences between
- * INTEGER and NativeInteger.
- * Basically, both are decoders and encoders of ASN.1 INTEGER type, but this
- * implementation deals with the standard (machine-specific) representation
- * of them instead of using the platform-independent buffer.
- */
-#include <asn_internal.h>
-#include <NativeInteger.h>
-
-/*
- * NativeInteger basic type description.
- */
-static ber_tlv_tag_t asn_DEF_NativeInteger_tags[] = {
- (ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
-};
-asn_TYPE_descriptor_t asn_DEF_NativeInteger = {
- "INTEGER", /* The ASN.1 type is still INTEGER */
- "INTEGER",
- NativeInteger_free,
- NativeInteger_print,
- asn_generic_no_constraint,
- NativeInteger_decode_ber,
- NativeInteger_encode_der,
- NativeInteger_decode_xer,
- NativeInteger_encode_xer,
- NativeInteger_decode_uper, /* Unaligned PER decoder */
- NativeInteger_encode_uper, /* Unaligned PER encoder */
- 0, /* Use generic outmost tag fetcher */
- asn_DEF_NativeInteger_tags,
- sizeof(asn_DEF_NativeInteger_tags) / sizeof(asn_DEF_NativeInteger_tags[0]),
- asn_DEF_NativeInteger_tags, /* Same as above */
- sizeof(asn_DEF_NativeInteger_tags) / sizeof(asn_DEF_NativeInteger_tags[0]),
- 0, /* No PER visible constraints */
- 0, 0, /* No members */
- 0 /* No specifics */
-};
-
-/*
- * Decode INTEGER type.
- */
-asn_dec_rval_t
-NativeInteger_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
- asn_TYPE_descriptor_t *td,
- void **nint_ptr, const void *buf_ptr, size_t size, int tag_mode) {
- long *native = (long *)*nint_ptr;
- asn_dec_rval_t rval;
- ber_tlv_len_t length;
-
- /*
- * If the structure is not there, allocate it.
- */
- if(native == NULL) {
- native = (long *)(*nint_ptr = CALLOC(1, sizeof(*native)));
- if(native == NULL) {
- rval.code = RC_FAIL;
- rval.consumed = 0;
- return rval;
- }
- }
-
- ASN_DEBUG("Decoding %s as INTEGER (tm=%d)",
- td->name, tag_mode);
-
- /*
- * Check tags.
- */
- rval = ber_check_tags(opt_codec_ctx, td, 0, buf_ptr, size,
- tag_mode, 0, &length, 0);
- if(rval.code != RC_OK)
- return rval;
-
- ASN_DEBUG("%s length is %d bytes", td->name, (int)length);
-
- /*
- * Make sure we have this length.
- */
- buf_ptr = ((const char *)buf_ptr) + rval.consumed;
- size -= rval.consumed;
- if(length > (ber_tlv_len_t)size) {
- rval.code = RC_WMORE;
- rval.consumed = 0;
- return rval;
- }
-
- /*
- * ASN.1 encoded INTEGER: buf_ptr, length
- * Fill the native, at the same time checking for overflow.
- * If overflow occured, return with RC_FAIL.
- */
- {
- INTEGER_t tmp;
- union {
- const void *constbuf;
- void *nonconstbuf;
- } unconst_buf;
- long l;
-
- unconst_buf.constbuf = buf_ptr;
- tmp.buf = (uint8_t *)unconst_buf.nonconstbuf;
- tmp.size = length;
-
- if(asn_INTEGER2long(&tmp, &l)) {
- rval.code = RC_FAIL;
- rval.consumed = 0;
- return rval;
- }
-
- *native = l;
- }
-
- rval.code = RC_OK;
- rval.consumed += length;
-
- ASN_DEBUG("Took %ld/%ld bytes to encode %s (%ld)",
- (long)rval.consumed, (long)length, td->name, (long)*native);
-
- return rval;
-}
-
-/*
- * Encode the NativeInteger using the standard INTEGER type DER encoder.
- */
-asn_enc_rval_t
-NativeInteger_encode_der(asn_TYPE_descriptor_t *sd, void *ptr,
- int tag_mode, ber_tlv_tag_t tag,
- asn_app_consume_bytes_f *cb, void *app_key) {
- unsigned long native = *(unsigned long *)ptr; /* Disable sign ext. */
- asn_enc_rval_t erval;
- INTEGER_t tmp;
-
-#ifdef WORDS_BIGENDIAN /* Opportunistic optimization */
-
- tmp.buf = (uint8_t *)&native;
- tmp.size = sizeof(native);
-
-#else /* Works even if WORDS_BIGENDIAN is not set where should've been */
- uint8_t buf[sizeof(native)];
- uint8_t *p;
-
- /* Prepare a fake INTEGER */
- for(p = buf + sizeof(buf) - 1; p >= buf; p--, native >>= 8)
- *p = native;
-
- tmp.buf = buf;
- tmp.size = sizeof(buf);
-#endif /* WORDS_BIGENDIAN */
-
- /* Encode fake INTEGER */
- erval = INTEGER_encode_der(sd, &tmp, tag_mode, tag, cb, app_key);
- if(erval.encoded == -1) {
- assert(erval.structure_ptr == &tmp);
- erval.structure_ptr = ptr;
- }
- return erval;
-}
-
-/*
- * Decode the chunk of XML text encoding INTEGER.
- */
-asn_dec_rval_t
-NativeInteger_decode_xer(asn_codec_ctx_t *opt_codec_ctx,
- asn_TYPE_descriptor_t *td, void **sptr, const char *opt_mname,
- const void *buf_ptr, size_t size) {
- asn_dec_rval_t rval;
- INTEGER_t st;
- void *st_ptr = (void *)&st;
- long *native = (long *)*sptr;
-
- if(!native) {
- native = (long *)(*sptr = CALLOC(1, sizeof(*native)));
- if(!native) _ASN_DECODE_FAILED;
- }
-
- memset(&st, 0, sizeof(st));
- rval = INTEGER_decode_xer(opt_codec_ctx, td, &st_ptr,
- opt_mname, buf_ptr, size);
- if(rval.code == RC_OK) {
- long l;
- if(asn_INTEGER2long(&st, &l)) {
- rval.code = RC_FAIL;
- rval.consumed = 0;
- } else {
- *native = l;
- }
- } else {
- /*
- * Cannot restart from the middle;
- * there is no place to save state in the native type.
- * Request a continuation from the very beginning.
- */
- rval.consumed = 0;
- }
- ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_INTEGER, &st);
- return rval;
-}
-
-
-asn_enc_rval_t
-NativeInteger_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
- int ilevel, enum xer_encoder_flags_e flags,
- asn_app_consume_bytes_f *cb, void *app_key) {
- char scratch[32]; /* Enough for 64-bit int */
- asn_enc_rval_t er;
- const long *native = (const long *)sptr;
-
- (void)ilevel;
- (void)flags;
-
- if(!native) _ASN_ENCODE_FAILED;
-
- er.encoded = snprintf(scratch, sizeof(scratch), "%ld", *native);
- if(er.encoded <= 0 || (size_t)er.encoded >= sizeof(scratch)
- || cb(scratch, er.encoded, app_key) < 0)
- _ASN_ENCODE_FAILED;
-
- _ASN_ENCODED_OK(er);
-}
-
-asn_dec_rval_t
-NativeInteger_decode_uper(asn_codec_ctx_t *opt_codec_ctx,
- asn_TYPE_descriptor_t *td,
- asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
-
- asn_dec_rval_t rval;
- long *native = (long *)*sptr;
- INTEGER_t tmpint;
- void *tmpintptr = &tmpint;
-
- (void)opt_codec_ctx;
- ASN_DEBUG("Decoding NativeInteger %s (UPER)", td->name);
-
- if(!native) {
- native = (long *)(*sptr = CALLOC(1, sizeof(*native)));
- if(!native) _ASN_DECODE_FAILED;
- }
-
- memset(&tmpint, 0, sizeof tmpint);
- rval = INTEGER_decode_uper(opt_codec_ctx, td, constraints,
- &tmpintptr, pd);
- if(rval.code == RC_OK) {
- if(asn_INTEGER2long(&tmpint, native))
- rval.code = RC_FAIL;
- else
- ASN_DEBUG("NativeInteger %s got value %ld",
- td->name, *native);
- }
- ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_INTEGER, &tmpint);
-
- return rval;
-}
-
-asn_enc_rval_t
-NativeInteger_encode_uper(asn_TYPE_descriptor_t *td,
- asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
- asn_enc_rval_t er;
- long native;
- INTEGER_t tmpint;
-
- if(!sptr) _ASN_ENCODE_FAILED;
-
- native = *(long *)sptr;
-
- ASN_DEBUG("Encoding NativeInteger %s %ld (UPER)", td->name, native);
-
- memset(&tmpint, 0, sizeof(tmpint));
- if(asn_long2INTEGER(&tmpint, native))
- _ASN_ENCODE_FAILED;
- er = INTEGER_encode_uper(td, constraints, &tmpint, po);
- ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_INTEGER, &tmpint);
- return er;
-}
-
-/*
- * INTEGER specific human-readable output.
- */
-int
-NativeInteger_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
- asn_app_consume_bytes_f *cb, void *app_key) {
- const long *native = (const long *)sptr;
- char scratch[32]; /* Enough for 64-bit int */
- int ret;
-
- (void)td; /* Unused argument */
- (void)ilevel; /* Unused argument */
-
- if(native) {
- ret = snprintf(scratch, sizeof(scratch), "%ld", *native);
- assert(ret > 0 && (size_t)ret < sizeof(scratch));
- return (cb(scratch, ret, app_key) < 0) ? -1 : 0;
- } else {
- return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
- }
-}
-
-void
-NativeInteger_free(asn_TYPE_descriptor_t *td, void *ptr, int contents_only) {
-
- if(!td || !ptr)
- return;
-
- ASN_DEBUG("Freeing %s as INTEGER (%d, %p, Native)",
- td->name, contents_only, ptr);
-
- if(!contents_only) {
- FREEMEM(ptr);
- }
-}
-
+++ /dev/null
-/*-
- * Copyright (c) 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-/*
- * This type differs from the standard INTEGER in that it is modelled using
- * the fixed machine type (long, int, short), so it can hold only values of
- * limited length. There is no type (i.e., NativeInteger_t, any integer type
- * will do).
- * This type may be used when integer range is limited by subtype constraints.
- */
-#ifndef _NativeInteger_H_
-#define _NativeInteger_H_
-
-#include <asn_application.h>
-#include <INTEGER.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern asn_TYPE_descriptor_t asn_DEF_NativeInteger;
-
-asn_struct_free_f NativeInteger_free;
-asn_struct_print_f NativeInteger_print;
-ber_type_decoder_f NativeInteger_decode_ber;
-der_type_encoder_f NativeInteger_encode_der;
-xer_type_decoder_f NativeInteger_decode_xer;
-xer_type_encoder_f NativeInteger_encode_xer;
-per_type_decoder_f NativeInteger_decode_uper;
-per_type_encoder_f NativeInteger_encode_uper;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _NativeInteger_H_ */
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1155-SMI"
- * found in "RFC1155-SMI.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#include <asn_internal.h>
-
-#include "NetworkAddress.h"
-
-static asn_TYPE_member_t asn_MBR_NetworkAddress_1[] = {
- { ATF_NOFLAGS, 0, offsetof(struct NetworkAddress, choice.internet),
- (ASN_TAG_CLASS_APPLICATION | (0 << 2)),
- 0,
- &asn_DEF_IpAddress,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "internet"
- },
-};
-static asn_TYPE_tag2member_t asn_MAP_NetworkAddress_tag2el_1[] = {
- { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 0, 0, 0 } /* internet at 113 */
-};
-static asn_CHOICE_specifics_t asn_SPC_NetworkAddress_specs_1 = {
- sizeof(struct NetworkAddress),
- offsetof(struct NetworkAddress, _asn_ctx),
- offsetof(struct NetworkAddress, present),
- sizeof(((struct NetworkAddress *)0)->present),
- asn_MAP_NetworkAddress_tag2el_1,
- 1, /* Count of tags in the map */
- 0,
- -1 /* Extensions start */
-};
-asn_TYPE_descriptor_t asn_DEF_NetworkAddress = {
- "NetworkAddress",
- "NetworkAddress",
- CHOICE_free,
- CHOICE_print,
- CHOICE_constraint,
- CHOICE_decode_ber,
- CHOICE_encode_der,
- CHOICE_decode_xer,
- CHOICE_encode_xer,
- 0, 0, /* No PER support, use "-gen-PER" to enable */
- CHOICE_outmost_tag,
- 0, /* No effective tags (pointer) */
- 0, /* No effective tags (count) */
- 0, /* No tags (pointer) */
- 0, /* No tags (count) */
- 0, /* No PER visible constraints */
- asn_MBR_NetworkAddress_1,
- 1, /* Elements count */
- &asn_SPC_NetworkAddress_specs_1 /* Additional specs */
-};
-
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1155-SMI"
- * found in "RFC1155-SMI.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#ifndef _NetworkAddress_H_
-#define _NetworkAddress_H_
-
-
-#include <asn_application.h>
-
-/* Including external dependencies */
-#include "IpAddress.h"
-#include <constr_CHOICE.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Dependencies */
-typedef enum NetworkAddress_PR {
- NetworkAddress_PR_NOTHING, /* No components present */
- NetworkAddress_PR_internet
-} NetworkAddress_PR;
-
-/* NetworkAddress */
-typedef struct NetworkAddress {
- NetworkAddress_PR present;
- union NetworkAddress_u {
- IpAddress_t internet;
- } choice;
-
- /* Context for parsing across buffer boundaries */
- asn_struct_ctx_t _asn_ctx;
-} NetworkAddress_t;
-
-/* Implementation */
-extern asn_TYPE_descriptor_t asn_DEF_NetworkAddress;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _NetworkAddress_H_ */
+++ /dev/null
-/*-
- * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-#include <asn_internal.h>
-#include <OBJECT_IDENTIFIER.h>
-#include <limits.h> /* for CHAR_BIT */
-#include <errno.h>
-
-/*
- * OBJECT IDENTIFIER basic type description.
- */
-static ber_tlv_tag_t asn_DEF_OBJECT_IDENTIFIER_tags[] = {
- (ASN_TAG_CLASS_UNIVERSAL | (6 << 2))
-};
-asn_TYPE_descriptor_t asn_DEF_OBJECT_IDENTIFIER = {
- "OBJECT IDENTIFIER",
- "OBJECT_IDENTIFIER",
- ASN__PRIMITIVE_TYPE_free,
- OBJECT_IDENTIFIER_print,
- OBJECT_IDENTIFIER_constraint,
- ber_decode_primitive,
- der_encode_primitive,
- OBJECT_IDENTIFIER_decode_xer,
- OBJECT_IDENTIFIER_encode_xer,
- 0, 0,
- 0, /* Use generic outmost tag fetcher */
- asn_DEF_OBJECT_IDENTIFIER_tags,
- sizeof(asn_DEF_OBJECT_IDENTIFIER_tags)
- / sizeof(asn_DEF_OBJECT_IDENTIFIER_tags[0]),
- asn_DEF_OBJECT_IDENTIFIER_tags, /* Same as above */
- sizeof(asn_DEF_OBJECT_IDENTIFIER_tags)
- / sizeof(asn_DEF_OBJECT_IDENTIFIER_tags[0]),
- 0, /* No PER visible constraints */
- 0, 0, /* No members */
- 0 /* No specifics */
-};
-
-
-int
-OBJECT_IDENTIFIER_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
- asn_app_constraint_failed_f *ctfailcb, void *app_key) {
- const OBJECT_IDENTIFIER_t *st = (const OBJECT_IDENTIFIER_t *)sptr;
-
- if(st && st->buf) {
- if(st->size < 1) {
- _ASN_CTFAIL(app_key, td,
- "%s: at least one numerical value "
- "expected (%s:%d)",
- td->name, __FILE__, __LINE__);
- return -1;
- }
- } else {
- _ASN_CTFAIL(app_key, td,
- "%s: value not given (%s:%d)",
- td->name, __FILE__, __LINE__);
- return -1;
- }
-
- return 0;
-}
-
-
-int
-OBJECT_IDENTIFIER_get_single_arc(uint8_t *arcbuf, unsigned int arclen, signed int add, void *rvbufp, unsigned int rvsize) {
- unsigned LE __attribute__ ((unused)) = 1; /* Little endian (x86) */
- uint8_t *arcend = arcbuf + arclen; /* End of arc */
- unsigned int cache = 0; /* No more than 14 significant bits */
- unsigned char *rvbuf = (unsigned char *)rvbufp;
- unsigned char *rvstart = rvbuf; /* Original start of the value buffer */
- int inc; /* Return value growth direction */
-
- rvsize *= CHAR_BIT; /* bytes to bits */
- arclen *= 7; /* bytes to bits */
-
- /*
- * The arc has the number of bits
- * cannot be represented using supplied return value type.
- */
- if(arclen > rvsize) {
- if(arclen > (rvsize + CHAR_BIT)) {
- errno = ERANGE; /* Overflow */
- return -1;
- } else {
- /*
- * Even if the number of bits in the arc representation
- * is higher than the width of supplied * return value
- * type, there is still possible to fit it when there
- * are few unused high bits in the arc value
- * representaion.
- *
- * Moreover, there is a possibility that the
- * number could actually fit the arc space, given
- * that add is negative, but we don't handle
- * such "temporary lack of precision" situation here.
- * May be considered as a bug.
- */
- uint8_t mask = (0xff << (7-(arclen - rvsize))) & 0x7f;
- if((*arcbuf & mask)) {
- errno = ERANGE; /* Overflow */
- return -1;
- }
- /* Fool the routine computing unused bits */
- arclen -= 7;
- cache = *arcbuf & 0x7f;
- arcbuf++;
- }
- }
-
- /* Faster path for common size */
- if(rvsize == (CHAR_BIT * sizeof(unsigned long))) {
- unsigned long accum;
- /* Gather all bits into the accumulator */
- for(accum = cache; arcbuf < arcend; arcbuf++)
- accum = (accum << 7) | (*arcbuf & ~0x80);
- if(accum < (unsigned)-add) {
- errno = ERANGE; /* Overflow */
- return -1;
- }
- *(unsigned long *)rvbuf = accum + add; /* alignment OK! */
- return 0;
- }
-
-#ifndef WORDS_BIGENDIAN
- if(*(unsigned char *)&LE) { /* Little endian (x86) */
- /* "Convert" to big endian */
- rvbuf += rvsize / CHAR_BIT - 1;
- rvstart--;
- inc = -1; /* Descending */
- } else
-#endif /* !WORDS_BIGENDIAN */
- inc = +1; /* Big endian is known [at compile time] */
-
- {
- int bits; /* typically no more than 3-4 bits */
-
- /* Clear the high unused bits */
- for(bits = rvsize - arclen;
- bits > CHAR_BIT;
- rvbuf += inc, bits -= CHAR_BIT)
- *rvbuf = 0;
-
- /* Fill the body of a value */
- for(; arcbuf < arcend; arcbuf++) {
- cache = (cache << 7) | (*arcbuf & 0x7f);
- bits += 7;
- if(bits >= CHAR_BIT) {
- bits -= CHAR_BIT;
- *rvbuf = (cache >> bits);
- rvbuf += inc;
- }
- }
- if(bits) {
- *rvbuf = cache;
- rvbuf += inc;
- }
- }
-
- if(add) {
- for(rvbuf -= inc; rvbuf != rvstart; rvbuf -= inc) {
- int v = add + *rvbuf;
- if(v & (-1 << CHAR_BIT)) {
- *rvbuf = (unsigned char)(v + (1 << CHAR_BIT));
- add = -1;
- } else {
- *rvbuf = v;
- break;
- }
- }
- if(rvbuf == rvstart) {
- /* No space to carry over */
- errno = ERANGE; /* Overflow */
- return -1;
- }
- }
-
- return 0;
-}
-
-ssize_t
-OBJECT_IDENTIFIER__dump_arc(uint8_t *arcbuf, int arclen, int add,
- asn_app_consume_bytes_f *cb, void *app_key) {
- char scratch[64]; /* Conservative estimate */
- unsigned long accum; /* Bits accumulator */
- char *p; /* Position in the scratch buffer */
-
- if(OBJECT_IDENTIFIER_get_single_arc(arcbuf, arclen, add,
- &accum, sizeof(accum)))
- return -1;
-
- if(accum) {
- ssize_t len;
-
- /* Fill the scratch buffer in reverse. */
- p = scratch + sizeof(scratch);
- for(; accum; accum /= 10)
- *(--p) = (char)(accum % 10) + 0x30; /* Put a digit */
-
- len = sizeof(scratch) - (p - scratch);
- if(cb(p, len, app_key) < 0)
- return -1;
- return len;
- } else {
- *scratch = 0x30;
- if(cb(scratch, 1, app_key) < 0)
- return -1;
- return 1;
- }
-}
-
-int
-OBJECT_IDENTIFIER_print_arc(uint8_t *arcbuf, int arclen, int add,
- asn_app_consume_bytes_f *cb, void *app_key) {
-
- if(OBJECT_IDENTIFIER__dump_arc(arcbuf, arclen, add, cb, app_key) < 0)
- return -1;
-
- return 0;
-}
-
-static ssize_t
-OBJECT_IDENTIFIER__dump_body(const OBJECT_IDENTIFIER_t *st, asn_app_consume_bytes_f *cb, void *app_key) {
- ssize_t wrote_len = 0;
- int startn;
- int add = 0;
- int i;
-
- for(i = 0, startn = 0; i < st->size; i++) {
- uint8_t b = st->buf[i];
- if((b & 0x80)) /* Continuation expected */
- continue;
-
- if(startn == 0) {
- /*
- * First two arcs are encoded through the backdoor.
- */
- if(i) {
- add = -80;
- if(cb("2", 1, app_key) < 0) return -1;
- } else if(b <= 39) {
- add = 0;
- if(cb("0", 1, app_key) < 0) return -1;
- } else if(b < 79) {
- add = -40;
- if(cb("1", 1, app_key) < 0) return -1;
- } else {
- add = -80;
- if(cb("2", 1, app_key) < 0) return -1;
- }
- wrote_len += 1;
- }
-
- if(cb(".", 1, app_key) < 0) /* Separate arcs */
- return -1;
-
- add = OBJECT_IDENTIFIER__dump_arc(&st->buf[startn],
- i - startn + 1, add, cb, app_key);
- if(add < 0) return -1;
- wrote_len += 1 + add;
- startn = i + 1;
- add = 0;
- }
-
- return wrote_len;
-}
-
-static enum xer_pbd_rval
-OBJECT_IDENTIFIER__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chunk_buf, size_t chunk_size) {
- OBJECT_IDENTIFIER_t *st = (OBJECT_IDENTIFIER_t *)sptr;
- const char *chunk_end = (const char *)chunk_buf + chunk_size;
- const char *endptr;
- long s_arcs[10];
- long *arcs = s_arcs;
- int arcs_count;
- int ret;
-
- (void)td;
-
- arcs_count = OBJECT_IDENTIFIER_parse_arcs(
- (const char *)chunk_buf, chunk_size, arcs,
- sizeof(s_arcs)/sizeof(s_arcs[0]), &endptr);
- if(arcs_count <= 0) {
- /* Expecting more than zero arcs */
- return XPBD_BROKEN_ENCODING;
- }
- if(endptr < chunk_end) {
- /* We have a tail of unrecognized data. Check its safety. */
- if(!xer_is_whitespace(endptr, chunk_end - endptr))
- return XPBD_BROKEN_ENCODING;
- }
-
- if((size_t)arcs_count > sizeof(s_arcs)/sizeof(s_arcs[0])) {
- arcs = (long *)MALLOC(arcs_count * sizeof(long));
- if(!arcs) return XPBD_SYSTEM_FAILURE;
- ret = OBJECT_IDENTIFIER_parse_arcs(
- (const char *)chunk_buf, chunk_size,
- arcs, arcs_count, &endptr);
- if(ret != arcs_count)
- return XPBD_SYSTEM_FAILURE; /* assert?.. */
- }
-
- /*
- * Convert arcs into BER representation.
- */
- ret = OBJECT_IDENTIFIER_set_arcs(st, arcs, sizeof(*arcs), arcs_count);
- if(arcs != s_arcs) FREEMEM(arcs);
-
- return ret ? XPBD_SYSTEM_FAILURE : XPBD_BODY_CONSUMED;
-}
-
-asn_dec_rval_t
-OBJECT_IDENTIFIER_decode_xer(asn_codec_ctx_t *opt_codec_ctx,
- asn_TYPE_descriptor_t *td, void **sptr, const char *opt_mname,
- const void *buf_ptr, size_t size) {
-
- return xer_decode_primitive(opt_codec_ctx, td,
- sptr, sizeof(OBJECT_IDENTIFIER_t), opt_mname,
- buf_ptr, size, OBJECT_IDENTIFIER__xer_body_decode);
-}
-
-asn_enc_rval_t
-OBJECT_IDENTIFIER_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
- int ilevel, enum xer_encoder_flags_e flags,
- asn_app_consume_bytes_f *cb, void *app_key) {
- const OBJECT_IDENTIFIER_t *st = (const OBJECT_IDENTIFIER_t *)sptr;
- asn_enc_rval_t er;
-
- (void)ilevel;
- (void)flags;
-
- if(!st || !st->buf)
- _ASN_ENCODE_FAILED;
-
- er.encoded = OBJECT_IDENTIFIER__dump_body(st, cb, app_key);
- if(er.encoded < 0) _ASN_ENCODE_FAILED;
-
- _ASN_ENCODED_OK(er);
-}
-
-int
-OBJECT_IDENTIFIER_print(asn_TYPE_descriptor_t *td, const void *sptr,
- int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
- const OBJECT_IDENTIFIER_t *st = (const OBJECT_IDENTIFIER_t *)sptr;
-
- (void)td; /* Unused argument */
- (void)ilevel; /* Unused argument */
-
- if(!st || !st->buf)
- return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
-
- /* Dump preamble */
- if(cb("{ ", 2, app_key) < 0)
- return -1;
-
- if(OBJECT_IDENTIFIER__dump_body(st, cb, app_key) < 0)
- return -1;
-
- return (cb(" }", 2, app_key) < 0) ? -1 : 0;
-}
-
-int
-OBJECT_IDENTIFIER_get_arcs(OBJECT_IDENTIFIER_t *oid, void *arcs,
- unsigned int arc_type_size, unsigned int arc_slots) {
- void *arcs_end = (char *)arcs + (arc_type_size * arc_slots);
- int num_arcs = 0;
- int startn = 0;
- int add = 0;
- int i;
-
- if(!oid || !oid->buf || (arc_slots && arc_type_size <= 1)) {
- errno = EINVAL;
- return -1;
- }
-
- for(i = 0; i < oid->size; i++) {
- uint8_t b = oid->buf[i];
- if((b & 0x80)) /* Continuation expected */
- continue;
-
- if(num_arcs == 0) {
- /*
- * First two arcs are encoded through the backdoor.
- */
- unsigned LE = 1; /* Little endian */
- int first_arc;
- num_arcs++;
- if(!arc_slots) { num_arcs++; continue; }
-
- if(i) first_arc = 2;
- else if(b <= 39) first_arc = 0;
- else if(b < 79) first_arc = 1;
- else first_arc = 2;
-
- add = -40 * first_arc;
- memset(arcs, 0, arc_type_size);
- *(unsigned char *)((char *)arcs
- + ((*(char *)&LE)?0:(arc_type_size - 1)))
- = first_arc;
- arcs = ((char *)arcs) + arc_type_size;
- }
-
- /* Decode, if has space */
- if(arcs < arcs_end) {
- if(OBJECT_IDENTIFIER_get_single_arc(&oid->buf[startn],
- i - startn + 1, add,
- arcs, arc_type_size))
- return -1;
- startn = i + 1;
- arcs = ((char *)arcs) + arc_type_size;
- add = 0;
- }
- num_arcs++;
- }
-
- return num_arcs;
-}
-
-
-/*
- * Save the single value as an object identifier arc.
- */
-int
-OBJECT_IDENTIFIER_set_single_arc(uint8_t *arcbuf, const void *arcval, unsigned int arcval_size, int prepared_order) {
- /*
- * The following conditions must hold:
- * assert(arcval);
- * assert(arcval_size > 0);
- * assert(arcval_size <= 16);
- * assert(arcbuf);
- */
-#ifdef WORDS_BIGENDIAN
- const unsigned isLittleEndian = 0;
-#else
- unsigned LE = 1;
- unsigned isLittleEndian = *(char *)&LE;
-#endif
- const uint8_t *tend, *tp;
- unsigned int cache;
- uint8_t *bp = arcbuf;
- int bits;
- uint8_t buffer[16];
-
- if(isLittleEndian && !prepared_order) {
- const uint8_t *a = (const unsigned char *)arcval + arcval_size - 1;
- const uint8_t *aend = (const uint8_t *)arcval;
- uint8_t *msb = buffer + arcval_size - 1;
- uint8_t *tb;
- for(tb = buffer; a >= aend; tb++, a--)
- if((*tb = *a) && (tb < msb))
- msb = tb;
- tend = &buffer[arcval_size];
- tp = msb; /* Most significant non-zero byte */
- } else {
- /* Look for most significant non-zero byte */
- tend = (const unsigned char *)arcval + arcval_size;
- for(tp = (const uint8_t *)arcval; tp < tend - 1; tp++)
- if(*tp) break;
- }
-
- /*
- * Split the value in 7-bits chunks.
- */
- bits = ((tend - tp) * CHAR_BIT) % 7;
- if(bits) {
- cache = *tp >> (CHAR_BIT - bits);
- if(cache) {
- *bp++ = cache | 0x80;
- cache = *tp++;
- bits = CHAR_BIT - bits;
- } else {
- bits = -bits;
- }
- } else {
- cache = 0;
- }
- for(; tp < tend; tp++) {
- cache = (cache << CHAR_BIT) + *tp;
- bits += CHAR_BIT;
- while(bits >= 7) {
- bits -= 7;
- *bp++ = 0x80 | (cache >> bits);
- }
- }
- if(bits) *bp++ = cache;
- bp[-1] &= 0x7f; /* Clear the last bit */
-
- return bp - arcbuf;
-}
-
-int
-OBJECT_IDENTIFIER_set_arcs(OBJECT_IDENTIFIER_t *oid, const void *arcs, unsigned int arc_type_size, unsigned int arc_slots) {
- uint8_t *buf;
- uint8_t *bp;
- unsigned LE = 1; /* Little endian (x86) */
- unsigned isLittleEndian = *((char *)&LE);
- unsigned int arc0;
- unsigned int arc1;
- unsigned size;
- unsigned i;
-
- if(!oid || !arcs || arc_type_size < 1
- || arc_type_size > 16
- || arc_slots < 2) {
- errno = EINVAL;
- return -1;
- }
-
- switch(arc_type_size) {
- case sizeof(char):
- arc0 = ((const unsigned char *)arcs)[0];
- arc1 = ((const unsigned char *)arcs)[1];
- break;
- case sizeof(short):
- arc0 = ((const unsigned short *)arcs)[0];
- arc1 = ((const unsigned short *)arcs)[1];
- break;
- case sizeof(int):
- arc0 = ((const unsigned int *)arcs)[0];
- arc1 = ((const unsigned int *)arcs)[1];
- break;
- default:
- arc1 = arc0 = 0;
- if(isLittleEndian) { /* Little endian (x86) */
- const unsigned char *ps, *pe;
- /* If more significant bytes are present,
- * make them > 255 quick */
- for(ps = (const unsigned char *)arcs + 1, pe = ps+arc_type_size;
- ps < pe; ps++)
- arc0 |= *ps, arc1 |= *(ps + arc_type_size);
- arc0 <<= CHAR_BIT, arc1 <<= CHAR_BIT;
- arc0 = *((const unsigned char *)arcs + 0);
- arc1 = *((const unsigned char *)arcs + arc_type_size);
- } else {
- const unsigned char *ps, *pe;
- /* If more significant bytes are present,
- * make them > 255 quick */
- for(ps = (const unsigned char *)arcs, pe = ps+arc_type_size - 1; ps < pe; ps++)
- arc0 |= *ps, arc1 |= *(ps + arc_type_size);
- arc0 = *((const unsigned char *)arcs + arc_type_size - 1);
- arc1 = *((const unsigned char *)arcs +(arc_type_size<< 1)-1);
- }
- }
-
- /*
- * The previous chapter left us with the first and the second arcs.
- * The values are not precise (that is, they are valid only if
- * they're less than 255), but OK for the purposes of making
- * the sanity test below.
- */
- if(arc0 <= 1) {
- if(arc1 >= 39) {
- /* 8.19.4: At most 39 subsequent values (including 0) */
- errno = ERANGE;
- return -1;
- }
- } else if(arc0 > 2) {
- /* 8.19.4: Only three values are allocated from the root node */
- errno = ERANGE;
- return -1;
- }
- /*
- * After above tests it is known that the value of arc0 is completely
- * trustworthy (0..2). However, the arc1's value is still meaningless.
- */
-
- /*
- * Roughly estimate the maximum size necessary to encode these arcs.
- * This estimation implicitly takes in account the following facts,
- * that cancel each other:
- * * the first two arcs are encoded in a single value.
- * * the first value may require more space (+1 byte)
- * * the value of the first arc which is in range (0..2)
- */
- size = ((arc_type_size * CHAR_BIT + 6) / 7) * arc_slots;
- bp = buf = (uint8_t *)MALLOC(size + 1);
- if(!buf) {
- /* ENOMEM */
- return -1;
- }
-
- /*
- * Encode the first two arcs.
- * These require special treatment.
- */
- {
- uint8_t *tp;
- uint8_t first_value[1 + 16]; /* of two arcs */
- uint8_t *fv = first_value;
-
- /*
- * Simulate first_value = arc0 * 40 + arc1;
- */
- /* Copy the second (1'st) arcs[1] into the first_value */
- *fv++ = 0;
- arcs = ((const char *)arcs) + arc_type_size;
- if(isLittleEndian) {
- const uint8_t *aend = (const unsigned char *)arcs - 1;
- const uint8_t *a1 = (const unsigned char *)arcs + arc_type_size - 1;
- for(; a1 > aend; fv++, a1--) *fv = *a1;
- } else {
- const uint8_t *a1 = (const uint8_t *)arcs;
- const uint8_t *aend = a1 + arc_type_size;
- for(; a1 < aend; fv++, a1++) *fv = *a1;
- }
- /* Increase the first_value by arc0 */
- arc0 *= 40; /* (0..80) */
- for(tp = first_value + arc_type_size; tp >= first_value; tp--) {
- unsigned int v = *tp;
- v += arc0;
- *tp = v;
- if(v >= (1 << CHAR_BIT)) arc0 = v >> CHAR_BIT;
- else break;
- }
-
- assert(tp >= first_value);
-
- bp += OBJECT_IDENTIFIER_set_single_arc(bp, first_value,
- fv - first_value, 1);
- }
-
- /*
- * Save the rest of arcs.
- */
- for(arcs = ((const char *)arcs) + arc_type_size, i = 2;
- i < arc_slots;
- i++, arcs = ((const char *)arcs) + arc_type_size) {
- bp += OBJECT_IDENTIFIER_set_single_arc(bp,
- arcs, arc_type_size, 0);
- }
-
- assert((unsigned)(bp - buf) <= size);
-
- /*
- * Replace buffer.
- */
- oid->size = bp - buf;
- bp = oid->buf;
- oid->buf = buf;
- if(bp) FREEMEM(bp);
-
- return 0;
-}
-
-
-int
-OBJECT_IDENTIFIER_parse_arcs(const char *oid_text, ssize_t oid_txt_length,
- long *arcs, unsigned int arcs_slots, const char **opt_oid_text_end) {
- unsigned int arcs_count = 0;
- const char *oid_end;
- long value = 0;
- enum {
- ST_SKIPSPACE,
- ST_WAITDIGITS, /* Next character is expected to be a digit */
- ST_DIGITS
- } state = ST_SKIPSPACE;
-
- if(!oid_text || oid_txt_length < -1 || (arcs_slots && !arcs)) {
- if(opt_oid_text_end) *opt_oid_text_end = oid_text;
- errno = EINVAL;
- return -1;
- }
-
- if(oid_txt_length == -1)
- oid_txt_length = strlen(oid_text);
-
- for(oid_end = oid_text + oid_txt_length; oid_text<oid_end; oid_text++) {
- switch(*oid_text) {
- case 0x09: case 0x0a: case 0x0d: case 0x20: /* whitespace */
- if(state == ST_SKIPSPACE) {
- continue;
- } else {
- break; /* Finish */
- }
- case 0x2e: /* '.' */
- if(state != ST_DIGITS
- || (oid_text + 1) == oid_end) {
- state = ST_WAITDIGITS;
- break;
- }
- if(arcs_count < arcs_slots)
- arcs[arcs_count] = value;
- arcs_count++;
- state = ST_WAITDIGITS;
- continue;
- case 0x30: case 0x31: case 0x32: case 0x33: case 0x34:
- case 0x35: case 0x36: case 0x37: case 0x38: case 0x39:
- if(state != ST_DIGITS) {
- state = ST_DIGITS;
- value = 0;
- }
- if(1) {
- long new_value = value * 10;
- if(new_value / 10 != value
- || (value = new_value + (*oid_text - 0x30)) < 0) {
- /* Overflow */
- state = ST_WAITDIGITS;
- break;
- }
- continue;
- }
- default:
- /* Unexpected symbols */
- state = ST_WAITDIGITS;
- break;
- } /* switch() */
- break;
- } /* for() */
-
-
- if(opt_oid_text_end) *opt_oid_text_end = oid_text;
-
- /* Finalize last arc */
- switch(state) {
- case ST_WAITDIGITS:
- errno = EINVAL;
- return -1;
- case ST_DIGITS:
- if(arcs_count < arcs_slots)
- arcs[arcs_count] = value;
- arcs_count++;
- /* Fall through */
- default:
- return arcs_count;
- }
-}
-
-
+++ /dev/null
-/*-
- * Copyright (c) 2003, 2004, 2005 Lev Walkin <vlm@lionet.info>.
- * All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-#ifndef _OBJECT_IDENTIFIER_H_
-#define _OBJECT_IDENTIFIER_H_
-
-#include <asn_application.h>
-#include <asn_codecs_prim.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef ASN__PRIMITIVE_TYPE_t OBJECT_IDENTIFIER_t;
-
-extern asn_TYPE_descriptor_t asn_DEF_OBJECT_IDENTIFIER;
-
-asn_struct_print_f OBJECT_IDENTIFIER_print;
-asn_constr_check_f OBJECT_IDENTIFIER_constraint;
-der_type_encoder_f OBJECT_IDENTIFIER_encode_der;
-xer_type_decoder_f OBJECT_IDENTIFIER_decode_xer;
-xer_type_encoder_f OBJECT_IDENTIFIER_encode_xer;
-
-/**********************************
- * Some handy conversion routines *
- **********************************/
-
-/*
- * This function fills an (_arcs) array with OBJECT IDENTIFIER arcs
- * up to specified (_arc_slots) elements.
- *
- * EXAMPLE:
- * void print_arcs(OBJECT_IDENTIFIER_t *oid) {
- * unsigned long fixed_arcs[10]; // Try with fixed space first
- * unsigned long *arcs = fixed_arcs;
- * int arc_type_size = sizeof(fixed_arcs[0]); // sizeof(long)
- * int arc_slots = sizeof(fixed_arcs)/sizeof(fixed_arcs[0]); // 10
- * int count; // Real number of arcs.
- * int i;
- *
- * count = OBJECT_IDENTIFIER_get_arcs(oid, arcs,
- * arc_type_size, arc_slots);
- * // If necessary, reallocate arcs array and try again.
- * if(count > arc_slots) {
- * arc_slots = count;
- * arcs = malloc(arc_type_size * arc_slots);
- * if(!arcs) return;
- * count = OBJECT_IDENTIFIER_get_arcs(oid, arcs,
- * arc_type_size, arc_slots);
- * assert(count == arc_slots);
- * }
- *
- * // Print the contents of the arcs array.
- * for(i = 0; i < count; i++)
- * printf("%d\n", arcs[i]);
- *
- * // Avoid memory leak.
- * if(arcs != fixed_arcs) free(arcs);
- * }
- *
- * RETURN VALUES:
- * -1/EINVAL: Invalid arguments (oid is missing)
- * -1/ERANGE: One or more arcs have value out of array cell type range.
- * >=0: Number of arcs contained in the OBJECT IDENTIFIER
- *
- * WARNING: The function always returns the real number of arcs,
- * even if there is no sufficient (_arc_slots) provided.
- */
-int OBJECT_IDENTIFIER_get_arcs(OBJECT_IDENTIFIER_t *_oid,
- void *_arcs, /* e.g., unsigned int arcs[N] */
- unsigned int _arc_type_size, /* e.g., sizeof(arcs[0]) */
- unsigned int _arc_slots /* e.g., N */);
-
-/*
- * This functions initializes the OBJECT IDENTIFIER object with
- * the given set of arcs.
- * The minimum of two arcs must be present; some restrictions apply.
- * RETURN VALUES:
- * -1/EINVAL: Invalid arguments
- * -1/ERANGE: The first two arcs do not conform to ASN.1 restrictions.
- * -1/ENOMEM: Memory allocation failed
- * 0: The object was initialized with new arcs.
- */
-int OBJECT_IDENTIFIER_set_arcs(OBJECT_IDENTIFIER_t *_oid,
- const void *_arcs, /* e.g., unsigned int arcs[N] */
- unsigned int _arc_type_size, /* e.g., sizeof(arcs[0]) */
- unsigned int _arc_slots /* e.g., N */);
-
-/*
- * Print the specified OBJECT IDENTIFIER arc.
- */
-int OBJECT_IDENTIFIER_print_arc(uint8_t *arcbuf, int arclen,
- int add, /* Arbitrary offset, required to process the first two arcs */
- asn_app_consume_bytes_f *cb, void *app_key);
-
-/* Same as above, but returns the number of written digits, instead of 0 */
-ssize_t OBJECT_IDENTIFIER__dump_arc(uint8_t *arcbuf, int arclen, int add,
- asn_app_consume_bytes_f *cb, void *app_key);
-
-/*
- * Parse the OBJECT IDENTIFIER textual representation ("1.3.6.1.4.1.9363").
- * No arc can exceed the (0..signed_long_max) range (typically, 0..2G if L32).
- * This function is not specific to OBJECT IDENTIFIER, it may be used to parse
- * the RELATIVE-OID data, or any other data consisting of dot-separated
- * series of numeric values.
- *
- * If (oid_txt_length == -1), the strlen() will be invoked to determine the
- * size of the (oid_text) string.
- *
- * After return, the optional (opt_oid_text_end) is set to the character after
- * the last parsed one. (opt_oid_text_end) is never less than (oid_text).
- *
- * RETURN VALUES:
- * -1: Parse error.
- * >= 0: Number of arcs contained in the OBJECT IDENTIFIER.
- *
- * WARNING: The function always returns the real number of arcs,
- * even if there is no sufficient (_arc_slots) provided.
- * This is useful for (_arc_slots) value estimation.
- */
-int OBJECT_IDENTIFIER_parse_arcs(const char *oid_text, ssize_t oid_txt_length,
- long arcs[], unsigned int arcs_slots, const char **opt_oid_text_end);
-
-/*
- * Internal functions.
- * Used by RELATIVE-OID implementation in particular.
- */
-int OBJECT_IDENTIFIER_get_single_arc(uint8_t *arcbuf, unsigned int arclen,
- signed int add, void *value, unsigned int value_size);
-int OBJECT_IDENTIFIER_set_single_arc(uint8_t *arcbuf,
- const void *arcval, unsigned int arcval_size, int _prepared_order);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _OBJECT_IDENTIFIER_H_ */
+++ /dev/null
-/*-
- * Copyright (c) 2003, 2004, 2005, 2006 Lev Walkin <vlm@lionet.info>.
- * All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-#include <asn_internal.h>
-#include <OCTET_STRING.h>
-#include <BIT_STRING.h> /* for .bits_unused member */
-#include <errno.h>
-
-/*
- * OCTET STRING basic type description.
- */
-static ber_tlv_tag_t asn_DEF_OCTET_STRING_tags[] = {
- (ASN_TAG_CLASS_UNIVERSAL | (4 << 2))
-};
-static asn_OCTET_STRING_specifics_t asn_DEF_OCTET_STRING_specs = {
- sizeof(OCTET_STRING_t),
- offsetof(OCTET_STRING_t, _asn_ctx),
- 0
-};
-static asn_per_constraint_t asn_DEF_OCTET_STRING_constraint = {
- APC_SEMI_CONSTRAINED, -1, -1, 0, 0
-};
-asn_TYPE_descriptor_t asn_DEF_OCTET_STRING = {
- "OCTET STRING", /* Canonical name */
- "OCTET_STRING", /* XML tag name */
- OCTET_STRING_free,
- OCTET_STRING_print, /* non-ascii stuff, generally */
- asn_generic_no_constraint,
- OCTET_STRING_decode_ber,
- OCTET_STRING_encode_der,
- OCTET_STRING_decode_xer_hex,
- OCTET_STRING_encode_xer,
- OCTET_STRING_decode_uper, /* Unaligned PER decoder */
- OCTET_STRING_encode_uper, /* Unaligned PER encoder */
- 0, /* Use generic outmost tag fetcher */
- asn_DEF_OCTET_STRING_tags,
- sizeof(asn_DEF_OCTET_STRING_tags)
- / sizeof(asn_DEF_OCTET_STRING_tags[0]),
- asn_DEF_OCTET_STRING_tags, /* Same as above */
- sizeof(asn_DEF_OCTET_STRING_tags)
- / sizeof(asn_DEF_OCTET_STRING_tags[0]),
- 0, /* No PER visible constraints */
- 0, 0, /* No members */
- &asn_DEF_OCTET_STRING_specs
-};
-
-#undef _CH_PHASE
-#undef NEXT_PHASE
-#undef PREV_PHASE
-#define _CH_PHASE(ctx, inc) do { \
- if(ctx->phase == 0) \
- ctx->context = 0; \
- ctx->phase += inc; \
- } while(0)
-#define NEXT_PHASE(ctx) _CH_PHASE(ctx, +1)
-#define PREV_PHASE(ctx) _CH_PHASE(ctx, -1)
-
-#undef ADVANCE
-#define ADVANCE(num_bytes) do { \
- size_t num = (num_bytes); \
- buf_ptr = ((const char *)buf_ptr) + num; \
- size -= num; \
- consumed_myself += num; \
- } while(0)
-
-#undef RETURN
-#define RETURN(_code) do { \
- asn_dec_rval_t tmprval; \
- tmprval.code = _code; \
- tmprval.consumed = consumed_myself; \
- return tmprval; \
- } while(0)
-
-#undef APPEND
-#define APPEND(bufptr, bufsize) do { \
- size_t _bs = (bufsize); /* Append size */ \
- size_t _ns = ctx->context; /* Allocated now */ \
- size_t _es = st->size + _bs; /* Expected size */ \
- /* int is really a typeof(st->size): */ \
- if((int)_es < 0) RETURN(RC_FAIL); \
- if(_ns <= _es) { \
- void *ptr; \
- /* Be nice and round to the memory allocator */ \
- do { _ns = _ns ? _ns << 1 : 16; } \
- while(_ns <= _es); \
- /* int is really a typeof(st->size): */ \
- if((int)_ns < 0) RETURN(RC_FAIL); \
- ptr = REALLOC(st->buf, _ns); \
- if(ptr) { \
- st->buf = (uint8_t *)ptr; \
- ctx->context = _ns; \
- } else { \
- RETURN(RC_FAIL); \
- } \
- ASN_DEBUG("Reallocating into %ld", (long)_ns); \
- } \
- memcpy(st->buf + st->size, bufptr, _bs); \
- /* Convenient nul-termination */ \
- st->buf[_es] = '\0'; \
- st->size = _es; \
- } while(0)
-
-/*
- * Internal variant of the OCTET STRING.
- */
-typedef enum OS_type {
- _TT_GENERIC = 0, /* Just a random OCTET STRING */
- _TT_BIT_STRING = 1, /* BIT STRING type, a special case */
- _TT_ANY = 2 /* ANY type, a special case too */
-} OS_type_e;
-
-/*
- * The main reason why ASN.1 is still alive is that too much time and effort
- * is necessary for learning it more or less adequately, thus creating a gut
- * necessity to demonstrate that aquired skill everywhere afterwards.
- * No, I am not going to explain what the following stuff is.
- */
-struct _stack_el {
- ber_tlv_len_t left; /* What's left to read (or -1) */
- ber_tlv_len_t got; /* What was actually processed */
- int cont_level; /* Depth of subcontainment */
- int want_nulls; /* Want null "end of content" octets? */
- int bits_chopped; /* Flag in BIT STRING mode */
- ber_tlv_tag_t tag; /* For debugging purposes */
- struct _stack_el *prev;
- struct _stack_el *next;
-};
-struct _stack {
- struct _stack_el *tail;
- struct _stack_el *cur_ptr;
-};
-
-static struct _stack_el *
-OS__add_stack_el(struct _stack *st) {
- struct _stack_el *nel;
-
- /*
- * Reuse the old stack frame or allocate a new one.
- */
- if(st->cur_ptr && st->cur_ptr->next) {
- nel = st->cur_ptr->next;
- nel->bits_chopped = 0;
- nel->got = 0;
- /* Retain the nel->cont_level, it's correct. */
- } else {
- nel = (struct _stack_el *)CALLOC(1, sizeof(struct _stack_el));
- if(nel == NULL)
- return NULL;
-
- if(st->tail) {
- /* Increase a subcontainment depth */
- nel->cont_level = st->tail->cont_level + 1;
- st->tail->next = nel;
- }
- nel->prev = st->tail;
- st->tail = nel;
- }
-
- st->cur_ptr = nel;
-
- return nel;
-}
-
-static struct _stack *
-_new_stack() {
- return (struct _stack *)CALLOC(1, sizeof(struct _stack));
-}
-
-/*
- * Decode OCTET STRING type.
- */
-asn_dec_rval_t
-OCTET_STRING_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
- asn_TYPE_descriptor_t *td,
- void **sptr, const void *buf_ptr, size_t size, int tag_mode) {
- asn_OCTET_STRING_specifics_t *specs = td->specifics
- ? (asn_OCTET_STRING_specifics_t *)td->specifics
- : &asn_DEF_OCTET_STRING_specs;
- BIT_STRING_t *st = (BIT_STRING_t *)*sptr;
- asn_dec_rval_t rval;
- asn_struct_ctx_t *ctx;
- ssize_t consumed_myself = 0;
- struct _stack *stck; /* Expectations stack structure */
- struct _stack_el *sel = 0; /* Stack element */
- int tlv_constr;
- OS_type_e type_variant = (OS_type_e)specs->subvariant;
-
- ASN_DEBUG("Decoding %s as %s (frame %ld)",
- td->name,
- (type_variant == _TT_GENERIC) ?
- "OCTET STRING" : "OS-SpecialCase",
- (long)size);
-
- /*
- * Create the string if does not exist.
- */
- if(st == NULL) {
- st = (BIT_STRING_t *)(*sptr = CALLOC(1, specs->struct_size));
- if(st == NULL) RETURN(RC_FAIL);
- }
-
- /* Restore parsing context */
- ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset);
-
- switch(ctx->phase) {
- case 0:
- /*
- * Check tags.
- */
- rval = ber_check_tags(opt_codec_ctx, td, ctx,
- buf_ptr, size, tag_mode, -1,
- &ctx->left, &tlv_constr);
- if(rval.code != RC_OK)
- return rval;
-
- if(tlv_constr) {
- /*
- * Complex operation, requires stack of expectations.
- */
- ctx->ptr = _new_stack();
- if(ctx->ptr) {
- stck = (struct _stack *)ctx->ptr;
- } else {
- RETURN(RC_FAIL);
- }
- } else {
- /*
- * Jump into stackless primitive decoding.
- */
- _CH_PHASE(ctx, 3);
- if(type_variant == _TT_ANY && tag_mode != 1)
- APPEND(buf_ptr, rval.consumed);
- ADVANCE(rval.consumed);
- goto phase3;
- }
-
- NEXT_PHASE(ctx);
- /* Fall through */
- case 1:
- phase1:
- /*
- * Fill the stack with expectations.
- */
- stck = (struct _stack *)ctx->ptr;
- sel = stck->cur_ptr;
- do {
- ber_tlv_tag_t tlv_tag;
- ber_tlv_len_t tlv_len;
- ber_tlv_tag_t expected_tag;
- ssize_t tl, ll, tlvl;
- /* This one works even if (sel->left == -1) */
- ssize_t Left = ((!sel||(size_t)sel->left >= size)
- ?(ssize_t)size:sel->left);
-
-
- ASN_DEBUG("%p, s->l=%ld, s->wn=%ld, s->g=%ld\n", sel,
- (long)(sel?sel->left:0),
- (long)(sel?sel->want_nulls:0),
- (long)(sel?sel->got:0)
- );
- if(sel && sel->left <= 0 && sel->want_nulls == 0) {
- if(sel->prev) {
- struct _stack_el *prev = sel->prev;
- if(prev->left != -1) {
- if(prev->left < sel->got)
- RETURN(RC_FAIL);
- prev->left -= sel->got;
- }
- prev->got += sel->got;
- sel = stck->cur_ptr = prev;
- if(!sel) break;
- tlv_constr = 1;
- continue;
- } else {
- sel = stck->cur_ptr = 0;
- break; /* Nothing to wait */
- }
- }
-
- tl = ber_fetch_tag(buf_ptr, Left, &tlv_tag);
- ASN_DEBUG("fetch tag(size=%ld,L=%ld), %sstack, left=%ld, wn=%ld, tl=%ld",
- (long)size, (long)Left, sel?"":"!",
- (long)(sel?sel->left:0),
- (long)(sel?sel->want_nulls:0),
- (long)tl);
- switch(tl) {
- case -1: RETURN(RC_FAIL);
- case 0: RETURN(RC_WMORE);
- }
-
- tlv_constr = BER_TLV_CONSTRUCTED(buf_ptr);
-
- ll = ber_fetch_length(tlv_constr,
- (const char *)buf_ptr + tl,Left - tl,&tlv_len);
- ASN_DEBUG("Got tag=%s, tc=%d, left=%ld, tl=%ld, len=%ld, ll=%ld",
- ber_tlv_tag_string(tlv_tag), tlv_constr,
- (long)Left, (long)tl, (long)tlv_len, (long)ll);
- switch(ll) {
- case -1: RETURN(RC_FAIL);
- case 0: RETURN(RC_WMORE);
- }
-
- if(sel && sel->want_nulls
- && ((const uint8_t *)buf_ptr)[0] == 0
- && ((const uint8_t *)buf_ptr)[1] == 0)
- {
-
- ASN_DEBUG("Eat EOC; wn=%d--", sel->want_nulls);
-
- if(type_variant == _TT_ANY
- && (tag_mode != 1 || sel->cont_level))
- APPEND("\0\0", 2);
-
- ADVANCE(2);
- sel->got += 2;
- if(sel->left != -1) {
- sel->left -= 2; /* assert(sel->left >= 2) */
- }
-
- sel->want_nulls--;
- if(sel->want_nulls == 0) {
- /* Move to the next expectation */
- sel->left = 0;
- tlv_constr = 1;
- }
-
- continue;
- }
-
- /*
- * Set up expected tags,
- * depending on ASN.1 type being decoded.
- */
- switch(type_variant) {
- case _TT_BIT_STRING:
- /* X.690: 8.6.4.1, NOTE 2 */
- /* Fall through */
- case _TT_GENERIC:
- default:
- if(sel) {
- int level = sel->cont_level;
- if(level < td->all_tags_count) {
- expected_tag = td->all_tags[level];
- break;
- } else if(td->all_tags_count) {
- expected_tag = td->all_tags
- [td->all_tags_count - 1];
- break;
- }
- /* else, Fall through */
- }
- /* Fall through */
- case _TT_ANY:
- expected_tag = tlv_tag;
- break;
- }
-
-
- if(tlv_tag != expected_tag) {
- char buf[2][32];
- ber_tlv_tag_snprint(tlv_tag,
- buf[0], sizeof(buf[0]));
- ber_tlv_tag_snprint(td->tags[td->tags_count-1],
- buf[1], sizeof(buf[1]));
- ASN_DEBUG("Tag does not match expectation: %s != %s",
- buf[0], buf[1]);
- RETURN(RC_FAIL);
- }
-
- tlvl = tl + ll; /* Combined length of T and L encoding */
- if((tlv_len + tlvl) < 0) {
- /* tlv_len value is too big */
- ASN_DEBUG("TLV encoding + length (%ld) is too big",
- (long)tlv_len);
- RETURN(RC_FAIL);
- }
-
- /*
- * Append a new expectation.
- */
- sel = OS__add_stack_el(stck);
- if(!sel) RETURN(RC_FAIL);
-
- sel->tag = tlv_tag;
-
- sel->want_nulls = (tlv_len==-1);
- if(sel->prev && sel->prev->left != -1) {
- /* Check that the parent frame is big enough */
- if(sel->prev->left < tlvl + (tlv_len==-1?0:tlv_len))
- RETURN(RC_FAIL);
- if(tlv_len == -1)
- sel->left = sel->prev->left - tlvl;
- else
- sel->left = tlv_len;
- } else {
- sel->left = tlv_len;
- }
- if(type_variant == _TT_ANY
- && (tag_mode != 1 || sel->cont_level))
- APPEND(buf_ptr, tlvl);
- sel->got += tlvl;
- ADVANCE(tlvl);
-
- ASN_DEBUG("+EXPECT2 got=%ld left=%ld, wn=%d, clvl=%d",
- (long)sel->got, (long)sel->left,
- sel->want_nulls, sel->cont_level);
-
- } while(tlv_constr);
- if(sel == NULL) {
- /* Finished operation, "phase out" */
- ASN_DEBUG("Phase out");
- _CH_PHASE(ctx, +3);
- break;
- }
-
- NEXT_PHASE(ctx);
- /* Fall through */
- case 2:
- stck = (struct _stack *)ctx->ptr;
- sel = stck->cur_ptr;
- ASN_DEBUG("Phase 2: Need %ld bytes, size=%ld, alrg=%ld, wn=%d",
- (long)sel->left, (long)size, (long)sel->got,
- sel->want_nulls);
- {
- ber_tlv_len_t len;
-
- assert(sel->left >= 0);
-
- len = ((ber_tlv_len_t)size < sel->left)
- ? (ber_tlv_len_t)size : sel->left;
- if(len > 0) {
- if(type_variant == _TT_BIT_STRING
- && sel->bits_chopped == 0) {
- /* Put the unused-bits-octet away */
- st->bits_unused = *(const uint8_t *)buf_ptr;
- APPEND(((const char *)buf_ptr+1), (len - 1));
- sel->bits_chopped = 1;
- } else {
- APPEND(buf_ptr, len);
- }
- ADVANCE(len);
- sel->left -= len;
- sel->got += len;
- }
-
- if(sel->left) {
- ASN_DEBUG("OS left %ld, size = %ld, wn=%d\n",
- (long)sel->left, (long)size, sel->want_nulls);
- RETURN(RC_WMORE);
- }
-
- PREV_PHASE(ctx);
- goto phase1;
- }
- break;
- case 3:
- phase3:
- /*
- * Primitive form, no stack required.
- */
- assert(ctx->left >= 0);
-
- if(size < (size_t)ctx->left) {
- if(!size) RETURN(RC_WMORE);
- if(type_variant == _TT_BIT_STRING && !ctx->context) {
- st->bits_unused = *(const uint8_t *)buf_ptr;
- ctx->left--;
- ADVANCE(1);
- }
- APPEND(buf_ptr, size);
- assert(ctx->context > 0);
- ctx->left -= size;
- ADVANCE(size);
- RETURN(RC_WMORE);
- } else {
- if(type_variant == _TT_BIT_STRING
- && !ctx->context && ctx->left) {
- st->bits_unused = *(const uint8_t *)buf_ptr;
- ctx->left--;
- ADVANCE(1);
- }
- APPEND(buf_ptr, ctx->left);
- ADVANCE(ctx->left);
- ctx->left = 0;
-
- NEXT_PHASE(ctx);
- }
- break;
- }
-
- if(sel) {
- ASN_DEBUG("3sel p=%p, wn=%d, l=%ld, g=%ld, size=%ld",
- sel->prev, sel->want_nulls,
- (long)sel->left, (long)sel->got, (long)size);
- if(sel->prev || sel->want_nulls > 1 || sel->left > 0) {
- RETURN(RC_WMORE);
- }
- }
-
- /*
- * BIT STRING-specific processing.
- */
- if(type_variant == _TT_BIT_STRING && st->size) {
- /* Finalize BIT STRING: zero out unused bits. */
- st->buf[st->size-1] &= 0xff << st->bits_unused;
- }
-
- ASN_DEBUG("Took %ld bytes to encode %s: [%s]:%ld",
- (long)consumed_myself, td->name,
- (type_variant == _TT_GENERIC) ? (char *)st->buf : "<data>",
- (long)st->size);
-
-
- RETURN(RC_OK);
-}
-
-/*
- * Encode OCTET STRING type using DER.
- */
-asn_enc_rval_t
-OCTET_STRING_encode_der(asn_TYPE_descriptor_t *td, void *sptr,
- int tag_mode, ber_tlv_tag_t tag,
- asn_app_consume_bytes_f *cb, void *app_key) {
- asn_enc_rval_t er;
- asn_OCTET_STRING_specifics_t *specs = td->specifics
- ? (asn_OCTET_STRING_specifics_t *)td->specifics
- : &asn_DEF_OCTET_STRING_specs;
- BIT_STRING_t *st = (BIT_STRING_t *)sptr;
- OS_type_e type_variant = (OS_type_e)specs->subvariant;
- int fix_last_byte = 0;
-
- ASN_DEBUG("%s %s as OCTET STRING",
- cb?"Estimating":"Encoding", td->name);
-
- /*
- * Write tags.
- */
- if(type_variant != _TT_ANY || tag_mode == 1) {
- er.encoded = der_write_tags(td,
- (type_variant == _TT_BIT_STRING) + st->size,
- tag_mode, type_variant == _TT_ANY, tag, cb, app_key);
- if(er.encoded == -1) {
- er.failed_type = td;
- er.structure_ptr = sptr;
- return er;
- }
- } else {
- /* Disallow: [<tag>] IMPLICIT ANY */
- assert(type_variant != _TT_ANY || tag_mode != -1);
- er.encoded = 0;
- }
-
- if(!cb) {
- er.encoded += (type_variant == _TT_BIT_STRING) + st->size;
- _ASN_ENCODED_OK(er);
- }
-
- /*
- * Prepare to deal with the last octet of BIT STRING.
- */
- if(type_variant == _TT_BIT_STRING) {
- uint8_t b = st->bits_unused & 0x07;
- if(b && st->size) fix_last_byte = 1;
- _ASN_CALLBACK(&b, 1);
- er.encoded++;
- }
-
- /* Invoke callback for the main part of the buffer */
- _ASN_CALLBACK(st->buf, st->size - fix_last_byte);
-
- /* The last octet should be stripped off the unused bits */
- if(fix_last_byte) {
- uint8_t b = st->buf[st->size-1] & (0xff << st->bits_unused);
- _ASN_CALLBACK(&b, 1);
- }
-
- er.encoded += st->size;
- _ASN_ENCODED_OK(er);
-cb_failed:
- _ASN_ENCODE_FAILED;
-}
-
-asn_enc_rval_t
-OCTET_STRING_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
- int ilevel, enum xer_encoder_flags_e flags,
- asn_app_consume_bytes_f *cb, void *app_key) {
- static const char *h2c = "0123456789ABCDEF";
- const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr;
- asn_enc_rval_t er;
- char scratch[16 * 3 + 4];
- char *p = scratch;
- uint8_t *buf;
- uint8_t *end;
- size_t i;
-
- if(!st || !st->buf)
- _ASN_ENCODE_FAILED;
-
- er.encoded = 0;
-
- /*
- * Dump the contents of the buffer in hexadecimal.
- */
- buf = st->buf;
- end = buf + st->size;
- if(flags & XER_F_CANONICAL) {
- char *scend = scratch + (sizeof(scratch) - 2);
- for(; buf < end; buf++) {
- if(p >= scend) {
- _ASN_CALLBACK(scratch, p - scratch);
- er.encoded += p - scratch;
- p = scratch;
- }
- *p++ = h2c[(*buf >> 4) & 0x0F];
- *p++ = h2c[*buf & 0x0F];
- }
-
- _ASN_CALLBACK(scratch, p-scratch); /* Dump the rest */
- er.encoded += p - scratch;
- } else {
- for(i = 0; buf < end; buf++, i++) {
- if(!(i % 16) && (i || st->size > 16)) {
- _ASN_CALLBACK(scratch, p-scratch);
- er.encoded += (p-scratch);
- p = scratch;
- _i_ASN_TEXT_INDENT(1, ilevel);
- }
- *p++ = h2c[(*buf >> 4) & 0x0F];
- *p++ = h2c[*buf & 0x0F];
- *p++ = 0x20;
- }
- if(p - scratch) {
- p--; /* Remove the tail space */
- _ASN_CALLBACK(scratch, p-scratch); /* Dump the rest */
- er.encoded += p - scratch;
- if(st->size > 16)
- _i_ASN_TEXT_INDENT(1, ilevel-1);
- }
- }
-
- _ASN_ENCODED_OK(er);
-cb_failed:
- _ASN_ENCODE_FAILED;
-}
-
-static struct OCTET_STRING__xer_escape_table_s {
- char *string;
- int size;
-} OCTET_STRING__xer_escape_table[] = {
-#define OSXET(s) { s, sizeof(s) - 1 }
- OSXET("\074\156\165\154\057\076"), /* <nul/> */
- OSXET("\074\163\157\150\057\076"), /* <soh/> */
- OSXET("\074\163\164\170\057\076"), /* <stx/> */
- OSXET("\074\145\164\170\057\076"), /* <etx/> */
- OSXET("\074\145\157\164\057\076"), /* <eot/> */
- OSXET("\074\145\156\161\057\076"), /* <enq/> */
- OSXET("\074\141\143\153\057\076"), /* <ack/> */
- OSXET("\074\142\145\154\057\076"), /* <bel/> */
- OSXET("\074\142\163\057\076"), /* <bs/> */
- OSXET("\011"), /* \t */
- OSXET("\012"), /* \n */
- OSXET("\074\166\164\057\076"), /* <vt/> */
- OSXET("\074\146\146\057\076"), /* <ff/> */
- OSXET("\015"), /* \r */
- OSXET("\074\163\157\057\076"), /* <so/> */
- OSXET("\074\163\151\057\076"), /* <si/> */
- OSXET("\074\144\154\145\057\076"), /* <dle/> */
- OSXET("\074\144\143\061\057\076"), /* <de1/> */
- OSXET("\074\144\143\062\057\076"), /* <de2/> */
- OSXET("\074\144\143\063\057\076"), /* <de3/> */
- OSXET("\074\144\143\064\057\076"), /* <de4/> */
- OSXET("\074\156\141\153\057\076"), /* <nak/> */
- OSXET("\074\163\171\156\057\076"), /* <syn/> */
- OSXET("\074\145\164\142\057\076"), /* <etb/> */
- OSXET("\074\143\141\156\057\076"), /* <can/> */
- OSXET("\074\145\155\057\076"), /* <em/> */
- OSXET("\074\163\165\142\057\076"), /* <sub/> */
- OSXET("\074\145\163\143\057\076"), /* <esc/> */
- OSXET("\074\151\163\064\057\076"), /* <is4/> */
- OSXET("\074\151\163\063\057\076"), /* <is3/> */
- OSXET("\074\151\163\062\057\076"), /* <is2/> */
- OSXET("\074\151\163\061\057\076"), /* <is1/> */
- { 0, 0 }, /* " " */
- { 0, 0 }, /* ! */
- { 0, 0 }, /* \" */
- { 0, 0 }, /* # */
- { 0, 0 }, /* $ */
- { 0, 0 }, /* % */
- OSXET("\046\141\155\160\073"), /* & */
- { 0, 0 }, /* ' */
- {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, /* ()*+,-./ */
- {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, /* 01234567 */
- {0,0},{0,0},{0,0},{0,0}, /* 89:; */
- OSXET("\046\154\164\073"), /* < */
- { 0, 0 }, /* = */
- OSXET("\046\147\164\073"), /* > */
-};
-
-static int
-OS__check_escaped_control_char(const void *buf, int size) {
- size_t i;
- /*
- * Inefficient algorithm which translates the escape sequences
- * defined above into characters. Returns -1 if not found.
- * TODO: replace by a faster algorithm (bsearch(), hash or
- * nested table lookups).
- */
- for(i = 0; i < 32 /* Don't spend time on the bottom half */; i++) {
- struct OCTET_STRING__xer_escape_table_s *el;
- el = &OCTET_STRING__xer_escape_table[i];
- if(el->size == size && memcmp(buf, el->string, size) == 0)
- return i;
- }
- return -1;
-}
-
-static int
-OCTET_STRING__handle_control_chars(void *struct_ptr, const void *chunk_buf, size_t chunk_size) {
- /*
- * This might be one of the escape sequences
- * for control characters. Check it out.
- * #11.15.5
- */
- int control_char = OS__check_escaped_control_char(chunk_buf,chunk_size);
- if(control_char >= 0) {
- OCTET_STRING_t *st = (OCTET_STRING_t *)struct_ptr;
- void *p = REALLOC(st->buf, st->size + 2);
- if(p) {
- st->buf = (uint8_t *)p;
- st->buf[st->size++] = control_char;
- st->buf[st->size] = '\0'; /* nul-termination */
- return 0;
- }
- }
-
- return -1; /* No, it's not */
-}
-
-asn_enc_rval_t
-OCTET_STRING_encode_xer_utf8(asn_TYPE_descriptor_t *td, void *sptr,
- int ilevel, enum xer_encoder_flags_e flags,
- asn_app_consume_bytes_f *cb, void *app_key) {
- const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr;
- asn_enc_rval_t er;
- uint8_t *buf, *end;
- uint8_t *ss; /* Sequence start */
- ssize_t encoded_len = 0;
-
- (void)ilevel; /* Unused argument */
- (void)flags; /* Unused argument */
-
- if(!st || !st->buf)
- _ASN_ENCODE_FAILED;
-
- buf = st->buf;
- end = buf + st->size;
- for(ss = buf; buf < end; buf++) {
- unsigned int ch = *buf;
- int s_len; /* Special encoding sequence length */
-
- /*
- * Escape certain characters: X.680/11.15
- */
- if(ch < sizeof(OCTET_STRING__xer_escape_table)
- /sizeof(OCTET_STRING__xer_escape_table[0])
- && (s_len = OCTET_STRING__xer_escape_table[ch].size)) {
- if(((buf - ss) && cb(ss, buf - ss, app_key) < 0)
- || cb(OCTET_STRING__xer_escape_table[ch].string, s_len,
- app_key) < 0)
- _ASN_ENCODE_FAILED;
- encoded_len += (buf - ss) + s_len;
- ss = buf + 1;
- }
- }
-
- encoded_len += (buf - ss);
- if((buf - ss) && cb(ss, buf - ss, app_key) < 0)
- _ASN_ENCODE_FAILED;
-
- er.encoded = encoded_len;
- _ASN_ENCODED_OK(er);
-}
-
-/*
- * Convert from hexadecimal format (cstring): "AB CD EF"
- */
-static ssize_t OCTET_STRING__convert_hexadecimal(void *sptr, const void *chunk_buf, size_t chunk_size, int have_more) {
- OCTET_STRING_t *st = (OCTET_STRING_t *)sptr;
- const char *chunk_stop = (const char *)chunk_buf;
- const char *p = chunk_stop;
- const char *pend = p + chunk_size;
- unsigned int clv = 0;
- int half = 0; /* Half bit */
- uint8_t *buf;
-
- /* Reallocate buffer according to high cap estimation */
- ssize_t _ns = st->size + (chunk_size + 1) / 2;
- void *nptr = REALLOC(st->buf, _ns + 1);
- if(!nptr) return -1;
- st->buf = (uint8_t *)nptr;
- buf = st->buf + st->size;
-
- /*
- * If something like " a b c " appears here, the " a b":3 will be
- * converted, and the rest skipped. That is, unless buf_size is greater
- * than chunk_size, then it'll be equivalent to "ABC0".
- */
- for(; p < pend; p++) {
- int ch = *(const unsigned char *)p;
- switch(ch) {
- case 0x09: case 0x0a: case 0x0c: case 0x0d:
- case 0x20:
- /* Ignore whitespace */
- continue;
- case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: /*01234*/
- case 0x35: case 0x36: case 0x37: case 0x38: case 0x39: /*56789*/
- clv = (clv << 4) + (ch - 0x30);
- break;
- case 0x41: case 0x42: case 0x43: /* ABC */
- case 0x44: case 0x45: case 0x46: /* DEF */
- clv = (clv << 4) + (ch - 0x41 + 10);
- break;
- case 0x61: case 0x62: case 0x63: /* abc */
- case 0x64: case 0x65: case 0x66: /* def */
- clv = (clv << 4) + (ch - 0x61 + 10);
- break;
- default:
- *buf = 0; /* JIC */
- return -1;
- }
- if(half++) {
- half = 0;
- *buf++ = clv;
- chunk_stop = p + 1;
- }
- }
-
- /*
- * Check partial decoding.
- */
- if(half) {
- if(have_more) {
- /*
- * Partial specification is fine,
- * because no more more PXER_TEXT data is available.
- */
- *buf++ = clv << 4;
- chunk_stop = p;
- }
- } else {
- chunk_stop = p;
- }
-
- st->size = buf - st->buf; /* Adjust the buffer size */
- assert(st->size <= _ns);
- st->buf[st->size] = 0; /* Courtesy termination */
-
- return (chunk_stop - (const char *)chunk_buf); /* Converted size */
-}
-
-/*
- * Convert from binary format: "00101011101"
- */
-static ssize_t OCTET_STRING__convert_binary(void *sptr, const void *chunk_buf, size_t chunk_size, int have_more) {
- BIT_STRING_t *st = (BIT_STRING_t *)sptr;
- const char *p = (const char *)chunk_buf;
- const char *pend = p + chunk_size;
- int bits_unused = st->bits_unused & 0x7;
- uint8_t *buf;
-
- /* Reallocate buffer according to high cap estimation */
- ssize_t _ns = st->size + (chunk_size + 7) / 8;
- void *nptr = REALLOC(st->buf, _ns + 1);
- if(!nptr) return -1;
- st->buf = (uint8_t *)nptr;
- buf = st->buf + st->size;
-
- (void)have_more;
-
- if(bits_unused == 0)
- bits_unused = 8;
- else if(st->size)
- buf--;
-
- /*
- * Convert series of 0 and 1 into the octet string.
- */
- for(; p < pend; p++) {
- int ch = *(const unsigned char *)p;
- switch(ch) {
- case 0x09: case 0x0a: case 0x0c: case 0x0d:
- case 0x20:
- /* Ignore whitespace */
- break;
- case 0x30:
- case 0x31:
- if(bits_unused-- <= 0) {
- *++buf = 0; /* Clean the cell */
- bits_unused = 7;
- }
- *buf |= (ch&1) << bits_unused;
- break;
- default:
- st->bits_unused = bits_unused;
- return -1;
- }
- }
-
- if(bits_unused == 8) {
- st->size = buf - st->buf;
- st->bits_unused = 0;
- } else {
- st->size = buf - st->buf + 1;
- st->bits_unused = bits_unused;
- }
-
- assert(st->size <= _ns);
- st->buf[st->size] = 0; /* Courtesy termination */
-
- return chunk_size; /* Converted in full */
-}
-
-/*
- * Something like strtod(), but with stricter rules.
- */
-static int
-OS__strtoent(int base, const char *buf, const char *end, int32_t *ret_value) {
- int32_t val = 0;
- const char *p;
-
- for(p = buf; p < end; p++) {
- int ch = *p;
-
- /* Strange huge value */
- if((val * base + base) < 0)
- return -1;
-
- switch(ch) {
- case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: /*01234*/
- case 0x35: case 0x36: case 0x37: case 0x38: case 0x39: /*56789*/
- val = val * base + (ch - 0x30);
- break;
- case 0x41: case 0x42: case 0x43: /* ABC */
- case 0x44: case 0x45: case 0x46: /* DEF */
- val = val * base + (ch - 0x41 + 10);
- break;
- case 0x61: case 0x62: case 0x63: /* abc */
- case 0x64: case 0x65: case 0x66: /* def */
- val = val * base + (ch - 0x61 + 10);
- break;
- case 0x3b: /* ';' */
- *ret_value = val;
- return (p - buf) + 1;
- default:
- return -1; /* Character set error */
- }
- }
-
- *ret_value = -1;
- return (p - buf);
-}
-
-/*
- * Convert from the plain UTF-8 format, expanding entity references: "2 < 3"
- */
-static ssize_t OCTET_STRING__convert_entrefs(void *sptr, const void *chunk_buf, size_t chunk_size, int have_more) {
- OCTET_STRING_t *st = (OCTET_STRING_t *)sptr;
- const char *p = (const char *)chunk_buf;
- const char *pend = p + chunk_size;
- uint8_t *buf;
-
- /* Reallocate buffer */
- ssize_t _ns = st->size + chunk_size;
- void *nptr = REALLOC(st->buf, _ns + 1);
- if(!nptr) return -1;
- st->buf = (uint8_t *)nptr;
- buf = st->buf + st->size;
-
- /*
- * Convert series of 0 and 1 into the octet string.
- */
- for(; p < pend; p++) {
- int ch = *(const unsigned char *)p;
- int len; /* Length of the rest of the chunk */
-
- if(ch != 0x26 /* '&' */) {
- *buf++ = ch;
- continue; /* That was easy... */
- }
-
- /*
- * Process entity reference.
- */
- len = chunk_size - (p - (const char *)chunk_buf);
- if(len == 1 /* "&" */) goto want_more;
- if(p[1] == 0x23 /* '#' */) {
- const char *pval; /* Pointer to start of digits */
- int32_t val = 0; /* Entity reference value */
- int base;
-
- if(len == 2 /* "&#" */) goto want_more;
- if(p[2] == 0x78 /* 'x' */)
- pval = p + 3, base = 16;
- else
- pval = p + 2, base = 10;
- len = OS__strtoent(base, pval, p + len, &val);
- if(len == -1) {
- /* Invalid charset. Just copy verbatim. */
- *buf++ = ch;
- continue;
- }
- if(!len || pval[len-1] != 0x3b) goto want_more;
- assert(val > 0);
- p += (pval - p) + len - 1; /* Advance past entref */
-
- if(val < 0x80) {
- *buf++ = (char)val;
- } else if(val < 0x800) {
- *buf++ = 0xc0 | ((val >> 6));
- *buf++ = 0x80 | ((val & 0x3f));
- } else if(val < 0x10000) {
- *buf++ = 0xe0 | ((val >> 12));
- *buf++ = 0x80 | ((val >> 6) & 0x3f);
- *buf++ = 0x80 | ((val & 0x3f));
- } else if(val < 0x200000) {
- *buf++ = 0xf0 | ((val >> 18));
- *buf++ = 0x80 | ((val >> 12) & 0x3f);
- *buf++ = 0x80 | ((val >> 6) & 0x3f);
- *buf++ = 0x80 | ((val & 0x3f));
- } else if(val < 0x4000000) {
- *buf++ = 0xf8 | ((val >> 24));
- *buf++ = 0x80 | ((val >> 18) & 0x3f);
- *buf++ = 0x80 | ((val >> 12) & 0x3f);
- *buf++ = 0x80 | ((val >> 6) & 0x3f);
- *buf++ = 0x80 | ((val & 0x3f));
- } else {
- *buf++ = 0xfc | ((val >> 30) & 0x1);
- *buf++ = 0x80 | ((val >> 24) & 0x3f);
- *buf++ = 0x80 | ((val >> 18) & 0x3f);
- *buf++ = 0x80 | ((val >> 12) & 0x3f);
- *buf++ = 0x80 | ((val >> 6) & 0x3f);
- *buf++ = 0x80 | ((val & 0x3f));
- }
- } else {
- /*
- * Ugly, limited parsing of & > <
- */
- char *sc = (char *)memchr(p, 0x3b, len > 5 ? 5 : len);
- if(!sc) goto want_more;
- if((sc - p) == 4
- && p[1] == 0x61 /* 'a' */
- && p[2] == 0x6d /* 'm' */
- && p[3] == 0x70 /* 'p' */) {
- *buf++ = 0x26;
- p = sc;
- continue;
- }
- if((sc - p) == 3) {
- if(p[1] == 0x6c) {
- *buf = 0x3c; /* '<' */
- } else if(p[1] == 0x67) {
- *buf = 0x3e; /* '>' */
- } else {
- /* Unsupported entity reference */
- *buf++ = ch;
- continue;
- }
- if(p[2] != 0x74) {
- /* Unsupported entity reference */
- *buf++ = ch;
- continue;
- }
- buf++;
- p = sc;
- continue;
- }
- /* Unsupported entity reference */
- *buf++ = ch;
- }
-
- continue;
- want_more:
- if(have_more) {
- /*
- * We know that no more data (of the same type)
- * is coming. Copy the rest verbatim.
- */
- *buf++ = ch;
- continue;
- }
- chunk_size = (p - (const char *)chunk_buf);
- /* Processing stalled: need more data */
- break;
- }
-
- st->size = buf - st->buf;
- assert(st->size <= _ns);
- st->buf[st->size] = 0; /* Courtesy termination */
-
- return chunk_size; /* Converted in full */
-}
-
-/*
- * Decode OCTET STRING from the XML element's body.
- */
-static asn_dec_rval_t
-OCTET_STRING__decode_xer(asn_codec_ctx_t *opt_codec_ctx,
- asn_TYPE_descriptor_t *td, void **sptr,
- const char *opt_mname, const void *buf_ptr, size_t size,
- int (*opt_unexpected_tag_decoder)
- (void *struct_ptr, const void *chunk_buf, size_t chunk_size),
- ssize_t (*body_receiver)
- (void *struct_ptr, const void *chunk_buf, size_t chunk_size,
- int have_more)
-) {
- OCTET_STRING_t *st = (OCTET_STRING_t *)*sptr;
- asn_OCTET_STRING_specifics_t *specs = td->specifics
- ? (asn_OCTET_STRING_specifics_t *)td->specifics
- : &asn_DEF_OCTET_STRING_specs;
- const char *xml_tag = opt_mname ? opt_mname : td->xml_tag;
- asn_struct_ctx_t *ctx; /* Per-structure parser context */
- asn_dec_rval_t rval; /* Return value from the decoder */
- int st_allocated;
-
- /*
- * Create the string if does not exist.
- */
- if(!st) {
- st = (OCTET_STRING_t *)CALLOC(1, specs->struct_size);
- *sptr = (void *)st;
- if(!st) goto sta_failed;
- st_allocated = 1;
- } else {
- st_allocated = 0;
- }
- if(!st->buf) {
- /* This is separate from above section */
- st->buf = (uint8_t *)CALLOC(1, 1);
- if(!st->buf) {
- if(st_allocated) {
- *sptr = 0;
- goto stb_failed;
- } else {
- goto sta_failed;
- }
- }
- }
-
- /* Restore parsing context */
- ctx = (asn_struct_ctx_t *)(((char *)*sptr) + specs->ctx_offset);
-
- return xer_decode_general(opt_codec_ctx, ctx, *sptr, xml_tag,
- buf_ptr, size, opt_unexpected_tag_decoder, body_receiver);
-
-stb_failed:
- FREEMEM(st);
-sta_failed:
- rval.code = RC_FAIL;
- rval.consumed = 0;
- return rval;
-}
-
-/*
- * Decode OCTET STRING from the hexadecimal data.
- */
-asn_dec_rval_t
-OCTET_STRING_decode_xer_hex(asn_codec_ctx_t *opt_codec_ctx,
- asn_TYPE_descriptor_t *td, void **sptr,
- const char *opt_mname, const void *buf_ptr, size_t size) {
- return OCTET_STRING__decode_xer(opt_codec_ctx, td, sptr, opt_mname,
- buf_ptr, size, 0, OCTET_STRING__convert_hexadecimal);
-}
-
-/*
- * Decode OCTET STRING from the binary (0/1) data.
- */
-asn_dec_rval_t
-OCTET_STRING_decode_xer_binary(asn_codec_ctx_t *opt_codec_ctx,
- asn_TYPE_descriptor_t *td, void **sptr,
- const char *opt_mname, const void *buf_ptr, size_t size) {
- return OCTET_STRING__decode_xer(opt_codec_ctx, td, sptr, opt_mname,
- buf_ptr, size, 0, OCTET_STRING__convert_binary);
-}
-
-/*
- * Decode OCTET STRING from the string (ASCII/UTF-8) data.
- */
-asn_dec_rval_t
-OCTET_STRING_decode_xer_utf8(asn_codec_ctx_t *opt_codec_ctx,
- asn_TYPE_descriptor_t *td, void **sptr,
- const char *opt_mname, const void *buf_ptr, size_t size) {
- return OCTET_STRING__decode_xer(opt_codec_ctx, td, sptr, opt_mname,
- buf_ptr, size,
- OCTET_STRING__handle_control_chars,
- OCTET_STRING__convert_entrefs);
-}
-
-asn_dec_rval_t
-OCTET_STRING_decode_uper(asn_codec_ctx_t *opt_codec_ctx,
- asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints,
- void **sptr, asn_per_data_t *pd) {
-
- asn_OCTET_STRING_specifics_t *specs = td->specifics
- ? (asn_OCTET_STRING_specifics_t *)td->specifics
- : &asn_DEF_OCTET_STRING_specs;
- asn_per_constraint_t *ct = constraints ? &constraints->size
- : (td->per_constraints
- ? &td->per_constraints->size
- : &asn_DEF_OCTET_STRING_constraint);
- asn_dec_rval_t rval = { RC_OK, 0 };
- BIT_STRING_t *st = (BIT_STRING_t *)*sptr;
- ssize_t consumed_myself = 0;
- int repeat;
- int unit_bits = (specs->subvariant != 1) * 7 + 1;
-
- (void)opt_codec_ctx;
-
- /*
- * Allocate the string.
- */
- if(!st) {
- st = (BIT_STRING_t *)(*sptr = CALLOC(1, specs->struct_size));
- if(!st) RETURN(RC_FAIL);
- }
-
- ASN_DEBUG("PER Decoding %s %ld .. %ld bits %d",
- ct->flags & APC_EXTENSIBLE ? "extensible" : "fixed",
- ct->lower_bound, ct->upper_bound, ct->effective_bits);
-
- if(ct->flags & APC_EXTENSIBLE) {
- int inext = per_get_few_bits(pd, 1);
- if(inext < 0) RETURN(RC_WMORE);
- if(inext) ct = &asn_DEF_OCTET_STRING_constraint;
- consumed_myself = 0;
- }
-
- if(ct->effective_bits >= 0
- && (!st->buf || st->size < ct->upper_bound)) {
- FREEMEM(st->buf);
- if(unit_bits == 1) {
- st->size = (ct->upper_bound + 7) >> 3;
- } else {
- st->size = ct->upper_bound;
- }
- st->buf = (uint8_t *)MALLOC(st->size + 1);
- if(!st->buf) { st->size = 0; RETURN(RC_FAIL); }
- }
-
- /* X.691, #16.5: zero-length encoding */
- /* X.691, #16.6: short fixed length encoding (up to 2 octets) */
- /* X.691, #16.7: long fixed length encoding (up to 64K octets) */
- if(ct->effective_bits == 0) {
- int ret = per_get_many_bits(pd, st->buf, 0,
- unit_bits * ct->upper_bound);
- if(ret < 0) RETURN(RC_WMORE);
- consumed_myself += unit_bits * ct->upper_bound;
- st->buf[st->size] = 0;
- if(unit_bits == 1 && (ct->upper_bound & 0x7))
- st->bits_unused = 8 - (ct->upper_bound & 0x7);
- RETURN(RC_OK);
- }
-
- st->size = 0;
- do {
- ssize_t len_bytes;
- ssize_t len_bits;
- void *p;
- int ret;
-
- /* Get the PER length */
- len_bits = uper_get_length(pd, ct->effective_bits, &repeat);
- if(len_bits < 0) RETURN(RC_WMORE);
- len_bits += ct->lower_bound;
-
- ASN_DEBUG("Got PER length eb %ld, len %ld, %s (%s)",
- (long)ct->effective_bits, (long)len_bits,
- repeat ? "repeat" : "once", td->name);
- if(unit_bits == 1) {
- len_bytes = (len_bits + 7) >> 3;
- if(len_bits & 0x7)
- st->bits_unused = 8 - (len_bits & 0x7);
- /* len_bits be multiple of 16K if repeat is set */
- } else {
- len_bytes = len_bits;
- len_bits = len_bytes << 3;
- }
- p = REALLOC(st->buf, st->size + len_bytes + 1);
- if(!p) RETURN(RC_FAIL);
- st->buf = (uint8_t *)p;
-
- ret = per_get_many_bits(pd, &st->buf[st->size], 0, len_bits);
- if(ret < 0) RETURN(RC_WMORE);
- st->size += len_bytes;
- } while(repeat);
- st->buf[st->size] = 0; /* nul-terminate */
-
- return rval;
-}
-
-asn_enc_rval_t
-OCTET_STRING_encode_uper(asn_TYPE_descriptor_t *td,
- asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
-
- asn_OCTET_STRING_specifics_t *specs = td->specifics
- ? (asn_OCTET_STRING_specifics_t *)td->specifics
- : &asn_DEF_OCTET_STRING_specs;
- asn_per_constraint_t *ct = constraints ? &constraints->size
- : (td->per_constraints
- ? &td->per_constraints->size
- : &asn_DEF_OCTET_STRING_constraint);
- const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;
- int unit_bits = (specs->subvariant != 1) * 7 + 1;
- asn_enc_rval_t er;
- int ct_extensible = ct->flags & APC_EXTENSIBLE;
- int inext = 0; /* Lies not within extension root */
- int sizeinunits = st->size;
- const uint8_t *buf;
- int ret;
-
- if(!st || !st->buf)
- _ASN_ENCODE_FAILED;
-
- if(unit_bits == 1) {
- ASN_DEBUG("BIT STRING of %d bytes, %d bits unused",
- sizeinunits, st->bits_unused);
- sizeinunits = sizeinunits * 8 - (st->bits_unused & 0x07);
- }
-
- ASN_DEBUG("Encoding %s into %d units of %d bits"
- " (%d..%d, effective %d)%s",
- td->name, sizeinunits, unit_bits,
- ct->lower_bound, ct->upper_bound,
- ct->effective_bits, ct_extensible ? " EXT" : "");
-
- /* Figure out wheter size lies within PER visible consrtaint */
-
- if(ct->effective_bits >= 0) {
- if(sizeinunits < ct->lower_bound
- || sizeinunits > ct->upper_bound) {
- if(ct_extensible) {
- ct = &asn_DEF_OCTET_STRING_constraint;
- inext = 1;
- } else
- _ASN_ENCODE_FAILED;
- }
- } else {
- inext = 0;
- }
-
- if(ct_extensible) {
- /* Declare whether length is [not] within extension root */
- if(per_put_few_bits(po, inext, 1))
- _ASN_ENCODE_FAILED;
- }
-
- /* X.691, #16.5: zero-length encoding */
- /* X.691, #16.6: short fixed length encoding (up to 2 octets) */
- /* X.691, #16.7: long fixed length encoding (up to 64K octets) */
- if(ct->effective_bits >= 0) {
- ASN_DEBUG("Encoding %d bytes (%ld), length in %d bits",
- st->size, sizeinunits - ct->lower_bound,
- ct->effective_bits);
- ret = per_put_few_bits(po, sizeinunits - ct->lower_bound,
- ct->effective_bits);
- if(ret) _ASN_ENCODE_FAILED;
- ret = per_put_many_bits(po, st->buf, sizeinunits * unit_bits);
- if(ret) _ASN_ENCODE_FAILED;
- _ASN_ENCODED_OK(er);
- }
-
- ASN_DEBUG("Encoding %d bytes", st->size);
-
- if(sizeinunits == 0) {
- if(uper_put_length(po, 0))
- _ASN_ENCODE_FAILED;
- _ASN_ENCODED_OK(er);
- }
-
- buf = st->buf;
- while(sizeinunits) {
- ssize_t maySave = uper_put_length(po, sizeinunits);
- if(maySave < 0) _ASN_ENCODE_FAILED;
-
- ASN_DEBUG("Encoding %d of %d", maySave, sizeinunits);
-
- ret = per_put_many_bits(po, buf, maySave * unit_bits);
- if(ret) _ASN_ENCODE_FAILED;
-
- if(unit_bits == 1)
- buf += maySave >> 3;
- else
- buf += maySave;
- sizeinunits -= maySave;
- assert(!(maySave & 0x07) || !sizeinunits);
- }
-
- _ASN_ENCODED_OK(er);
-}
-
-int
-OCTET_STRING_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
- asn_app_consume_bytes_f *cb, void *app_key) {
- static const char *h2c = "0123456789ABCDEF";
- const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr;
- char scratch[16 * 3 + 4];
- char *p = scratch;
- uint8_t *buf;
- uint8_t *end;
- size_t i;
-
- (void)td; /* Unused argument */
-
- if(!st || !st->buf) return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
-
- /*
- * Dump the contents of the buffer in hexadecimal.
- */
- buf = st->buf;
- end = buf + st->size;
- for(i = 0; buf < end; buf++, i++) {
- if(!(i % 16) && (i || st->size > 16)) {
- if(cb(scratch, p - scratch, app_key) < 0)
- return -1;
- _i_INDENT(1);
- p = scratch;
- }
- *p++ = h2c[(*buf >> 4) & 0x0F];
- *p++ = h2c[*buf & 0x0F];
- *p++ = 0x20;
- }
-
- if(p > scratch) {
- p--; /* Remove the tail space */
- if(cb(scratch, p - scratch, app_key) < 0)
- return -1;
- }
-
- return 0;
-}
-
-int
-OCTET_STRING_print_utf8(asn_TYPE_descriptor_t *td, const void *sptr,
- int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
- const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr;
-
- (void)td; /* Unused argument */
- (void)ilevel; /* Unused argument */
-
- if(st && st->buf) {
- return (cb(st->buf, st->size, app_key) < 0) ? -1 : 0;
- } else {
- return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
- }
-}
-
-void
-OCTET_STRING_free(asn_TYPE_descriptor_t *td, void *sptr, int contents_only) {
- OCTET_STRING_t *st = (OCTET_STRING_t *)sptr;
- asn_OCTET_STRING_specifics_t *specs = td->specifics
- ? (asn_OCTET_STRING_specifics_t *)td->specifics
- : &asn_DEF_OCTET_STRING_specs;
- asn_struct_ctx_t *ctx = (asn_struct_ctx_t *)
- ((char *)st + specs->ctx_offset);
- struct _stack *stck;
-
- if(!td || !st)
- return;
-
- ASN_DEBUG("Freeing %s as OCTET STRING", td->name);
-
- if(st->buf) {
- FREEMEM(st->buf);
- }
-
- /*
- * Remove decode-time stack.
- */
- stck = (struct _stack *)ctx->ptr;
- if(stck) {
- while(stck->tail) {
- struct _stack_el *sel = stck->tail;
- stck->tail = sel->prev;
- FREEMEM(sel);
- }
- FREEMEM(stck);
- }
-
- if(!contents_only) {
- FREEMEM(st);
- }
-}
-
-/*
- * Conversion routines.
- */
-int
-OCTET_STRING_fromBuf(OCTET_STRING_t *st, const char *str, int len) {
- void *buf;
-
- if(st == 0 || (str == 0 && len)) {
- errno = EINVAL;
- return -1;
- }
-
- /*
- * Clear the OCTET STRING.
- */
- if(str == NULL) {
- FREEMEM(st->buf);
- st->buf = 0;
- st->size = 0;
- return 0;
- }
-
- /* Determine the original string size, if not explicitly given */
- if(len < 0)
- len = strlen(str);
-
- /* Allocate and fill the memory */
- buf = MALLOC(len + 1);
- if(buf == NULL)
- return -1;
-
- memcpy(buf, str, len);
- ((uint8_t *)buf)[len] = '\0'; /* Couldn't use memcpy(len+1)! */
- FREEMEM(st->buf);
- st->buf = (uint8_t *)buf;
- st->size = len;
-
- return 0;
-}
-
-OCTET_STRING_t *
-OCTET_STRING_new_fromBuf(asn_TYPE_descriptor_t *td, const char *str, int len) {
- asn_OCTET_STRING_specifics_t *specs = td->specifics
- ? (asn_OCTET_STRING_specifics_t *)td->specifics
- : &asn_DEF_OCTET_STRING_specs;
- OCTET_STRING_t *st;
-
- st = (OCTET_STRING_t *)CALLOC(1, specs->struct_size);
- if(st && str && OCTET_STRING_fromBuf(st, str, len)) {
- FREEMEM(st);
- st = NULL;
- }
-
- return st;
-}
-
+++ /dev/null
-/*-
- * Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-#ifndef _OCTET_STRING_H_
-#define _OCTET_STRING_H_
-
-#include <asn_application.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct OCTET_STRING {
- uint8_t *buf; /* Buffer with consecutive OCTET_STRING bits */
- int size; /* Size of the buffer */
-
- asn_struct_ctx_t _asn_ctx; /* Parsing across buffer boundaries */
-} OCTET_STRING_t;
-
-extern asn_TYPE_descriptor_t asn_DEF_OCTET_STRING;
-
-asn_struct_free_f OCTET_STRING_free;
-asn_struct_print_f OCTET_STRING_print;
-asn_struct_print_f OCTET_STRING_print_utf8;
-ber_type_decoder_f OCTET_STRING_decode_ber;
-der_type_encoder_f OCTET_STRING_encode_der;
-xer_type_decoder_f OCTET_STRING_decode_xer_hex; /* Hexadecimal */
-xer_type_decoder_f OCTET_STRING_decode_xer_binary; /* 01010111010 */
-xer_type_decoder_f OCTET_STRING_decode_xer_utf8; /* ASCII/UTF-8 */
-xer_type_encoder_f OCTET_STRING_encode_xer;
-xer_type_encoder_f OCTET_STRING_encode_xer_utf8;
-per_type_decoder_f OCTET_STRING_decode_uper;
-per_type_encoder_f OCTET_STRING_encode_uper;
-
-/******************************
- * Handy conversion routines. *
- ******************************/
-
-/*
- * This function clears the previous value of the OCTET STRING (if any)
- * and then allocates a new memory with the specified content (str/size).
- * If size = -1, the size of the original string will be determined
- * using strlen(str).
- * If str equals to NULL, the function will silently clear the
- * current contents of the OCTET STRING.
- * Returns 0 if it was possible to perform operation, -1 otherwise.
- */
-int OCTET_STRING_fromBuf(OCTET_STRING_t *s, const char *str, int size);
-
-/* Handy conversion from the C string into the OCTET STRING. */
-#define OCTET_STRING_fromString(s, str) OCTET_STRING_fromBuf(s, str, -1)
-
-/*
- * Allocate and fill the new OCTET STRING and return a pointer to the newly
- * allocated object. NULL is permitted in str: the function will just allocate
- * empty OCTET STRING.
- */
-OCTET_STRING_t *OCTET_STRING_new_fromBuf(asn_TYPE_descriptor_t *td,
- const char *str, int size);
-
-/****************************
- * Internally useful stuff. *
- ****************************/
-
-typedef struct asn_OCTET_STRING_specifics_s {
- /*
- * Target structure description.
- */
- int struct_size; /* Size of the structure */
- int ctx_offset; /* Offset of the asn_struct_ctx_t member */
-
- int subvariant; /* {0,1,2} for O-S, BIT STRING or ANY */
-} asn_OCTET_STRING_specifics_t;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _OCTET_STRING_H_ */
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1155-SMI"
- * found in "RFC1155-SMI.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#include <asn_internal.h>
-
-#include "ObjectName.h"
-
-int
-ObjectName_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
- asn_app_constraint_failed_f *ctfailcb, void *app_key) {
- /* Replace with underlying type checker */
- td->check_constraints = asn_DEF_OBJECT_IDENTIFIER.check_constraints;
- return td->check_constraints(td, sptr, ctfailcb, app_key);
-}
-
-/*
- * This type is implemented using OBJECT_IDENTIFIER,
- * so here we adjust the DEF accordingly.
- */
-static void
-ObjectName_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
- td->free_struct = asn_DEF_OBJECT_IDENTIFIER.free_struct;
- td->print_struct = asn_DEF_OBJECT_IDENTIFIER.print_struct;
- td->ber_decoder = asn_DEF_OBJECT_IDENTIFIER.ber_decoder;
- td->der_encoder = asn_DEF_OBJECT_IDENTIFIER.der_encoder;
- td->xer_decoder = asn_DEF_OBJECT_IDENTIFIER.xer_decoder;
- td->xer_encoder = asn_DEF_OBJECT_IDENTIFIER.xer_encoder;
- td->uper_decoder = asn_DEF_OBJECT_IDENTIFIER.uper_decoder;
- td->uper_encoder = asn_DEF_OBJECT_IDENTIFIER.uper_encoder;
- if(!td->per_constraints)
- td->per_constraints = asn_DEF_OBJECT_IDENTIFIER.per_constraints;
- td->elements = asn_DEF_OBJECT_IDENTIFIER.elements;
- td->elements_count = asn_DEF_OBJECT_IDENTIFIER.elements_count;
- td->specifics = asn_DEF_OBJECT_IDENTIFIER.specifics;
-}
-
-void
-ObjectName_free(asn_TYPE_descriptor_t *td,
- void *struct_ptr, int contents_only) {
- ObjectName_1_inherit_TYPE_descriptor(td);
- td->free_struct(td, struct_ptr, contents_only);
-}
-
-int
-ObjectName_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
- int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
- ObjectName_1_inherit_TYPE_descriptor(td);
- return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
-}
-
-asn_dec_rval_t
-ObjectName_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
- void **structure, const void *bufptr, size_t size, int tag_mode) {
- ObjectName_1_inherit_TYPE_descriptor(td);
- return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode);
-}
-
-asn_enc_rval_t
-ObjectName_encode_der(asn_TYPE_descriptor_t *td,
- void *structure, int tag_mode, ber_tlv_tag_t tag,
- asn_app_consume_bytes_f *cb, void *app_key) {
- ObjectName_1_inherit_TYPE_descriptor(td);
- return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
-}
-
-asn_dec_rval_t
-ObjectName_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
- void **structure, const char *opt_mname, const void *bufptr, size_t size) {
- ObjectName_1_inherit_TYPE_descriptor(td);
- return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size);
-}
-
-asn_enc_rval_t
-ObjectName_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
- int ilevel, enum xer_encoder_flags_e flags,
- asn_app_consume_bytes_f *cb, void *app_key) {
- ObjectName_1_inherit_TYPE_descriptor(td);
- return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
-}
-
-static ber_tlv_tag_t asn_DEF_ObjectName_tags_1[] = {
- (ASN_TAG_CLASS_UNIVERSAL | (6 << 2))
-};
-asn_TYPE_descriptor_t asn_DEF_ObjectName = {
- "ObjectName",
- "ObjectName",
- ObjectName_free,
- ObjectName_print,
- ObjectName_constraint,
- ObjectName_decode_ber,
- ObjectName_encode_der,
- ObjectName_decode_xer,
- ObjectName_encode_xer,
- 0, 0, /* No PER support, use "-gen-PER" to enable */
- 0, /* Use generic outmost tag fetcher */
- asn_DEF_ObjectName_tags_1,
- sizeof(asn_DEF_ObjectName_tags_1)
- /sizeof(asn_DEF_ObjectName_tags_1[0]), /* 1 */
- asn_DEF_ObjectName_tags_1, /* Same as above */
- sizeof(asn_DEF_ObjectName_tags_1)
- /sizeof(asn_DEF_ObjectName_tags_1[0]), /* 1 */
- 0, /* No PER visible constraints */
- 0, 0, /* No members */
- 0 /* No specifics */
-};
-
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1155-SMI"
- * found in "RFC1155-SMI.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#ifndef _ObjectName_H_
-#define _ObjectName_H_
-
-
-#include <asn_application.h>
-
-/* Including external dependencies */
-#include <OBJECT_IDENTIFIER.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* ObjectName */
-typedef OBJECT_IDENTIFIER_t ObjectName_t;
-
-/* Implementation */
-extern asn_TYPE_descriptor_t asn_DEF_ObjectName;
-asn_struct_free_f ObjectName_free;
-asn_struct_print_f ObjectName_print;
-asn_constr_check_f ObjectName_constraint;
-ber_type_decoder_f ObjectName_decode_ber;
-der_type_encoder_f ObjectName_encode_der;
-xer_type_decoder_f ObjectName_decode_xer;
-xer_type_encoder_f ObjectName_encode_xer;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _ObjectName_H_ */
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1155-SMI"
- * found in "RFC1155-SMI.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#include <asn_internal.h>
-
-#include "ObjectSyntax.h"
-
-static asn_TYPE_member_t asn_MBR_ObjectSyntax_1[] = {
- { ATF_NOFLAGS, 0, offsetof(struct ObjectSyntax, choice.simple),
- -1 /* Ambiguous tag (CHOICE?) */,
- 0,
- &asn_DEF_SimpleSyntax,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "simple"
- },
- { ATF_NOFLAGS, 0, offsetof(struct ObjectSyntax, choice.application_wide),
- -1 /* Ambiguous tag (CHOICE?) */,
- 0,
- &asn_DEF_ApplicationSyntax,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "application-wide"
- },
-};
-static asn_TYPE_tag2member_t asn_MAP_ObjectSyntax_tag2el_1[] = {
- { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 0 }, /* number at 73 */
- { (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 0, 0, 0 }, /* string at 76 */
- { (ASN_TAG_CLASS_UNIVERSAL | (5 << 2)), 0, 0, 0 }, /* empty at 82 */
- { (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)), 0, 0, 0 }, /* object at 79 */
- { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 1, 0, 0 }, /* internet at 113 */
- { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 1, 0, 0 }, /* counter at 91 */
- { (ASN_TAG_CLASS_APPLICATION | (2 << 2)), 1, 0, 0 }, /* gauge at 94 */
- { (ASN_TAG_CLASS_APPLICATION | (3 << 2)), 1, 0, 0 }, /* ticks at 97 */
- { (ASN_TAG_CLASS_APPLICATION | (4 << 2)), 1, 0, 0 } /* arbitrary at 104 */
-};
-static asn_CHOICE_specifics_t asn_SPC_ObjectSyntax_specs_1 = {
- sizeof(struct ObjectSyntax),
- offsetof(struct ObjectSyntax, _asn_ctx),
- offsetof(struct ObjectSyntax, present),
- sizeof(((struct ObjectSyntax *)0)->present),
- asn_MAP_ObjectSyntax_tag2el_1,
- 9, /* Count of tags in the map */
- 0,
- -1 /* Extensions start */
-};
-asn_TYPE_descriptor_t asn_DEF_ObjectSyntax = {
- "ObjectSyntax",
- "ObjectSyntax",
- CHOICE_free,
- CHOICE_print,
- CHOICE_constraint,
- CHOICE_decode_ber,
- CHOICE_encode_der,
- CHOICE_decode_xer,
- CHOICE_encode_xer,
- 0, 0, /* No PER support, use "-gen-PER" to enable */
- CHOICE_outmost_tag,
- 0, /* No effective tags (pointer) */
- 0, /* No effective tags (count) */
- 0, /* No tags (pointer) */
- 0, /* No tags (count) */
- 0, /* No PER visible constraints */
- asn_MBR_ObjectSyntax_1,
- 2, /* Elements count */
- &asn_SPC_ObjectSyntax_specs_1 /* Additional specs */
-};
-
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1155-SMI"
- * found in "RFC1155-SMI.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#ifndef _ObjectSyntax_H_
-#define _ObjectSyntax_H_
-
-
-#include <asn_application.h>
-
-/* Including external dependencies */
-#include "SimpleSyntax.h"
-#include "ApplicationSyntax.h"
-#include <constr_CHOICE.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Dependencies */
-typedef enum ObjectSyntax_PR {
- ObjectSyntax_PR_NOTHING, /* No components present */
- ObjectSyntax_PR_simple,
- ObjectSyntax_PR_application_wide
-} ObjectSyntax_PR;
-
-/* ObjectSyntax */
-typedef struct ObjectSyntax {
- ObjectSyntax_PR present;
- union ObjectSyntax_u {
- SimpleSyntax_t simple;
- ApplicationSyntax_t application_wide;
- } choice;
-
- /* Context for parsing across buffer boundaries */
- asn_struct_ctx_t _asn_ctx;
-} ObjectSyntax_t;
-
-/* Implementation */
-extern asn_TYPE_descriptor_t asn_DEF_ObjectSyntax;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _ObjectSyntax_H_ */
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1155-SMI"
- * found in "RFC1155-SMI.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#include <asn_internal.h>
-
-#include "Opaque.h"
-
-int
-Opaque_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
- asn_app_constraint_failed_f *ctfailcb, void *app_key) {
- /* Replace with underlying type checker */
- td->check_constraints = asn_DEF_OCTET_STRING.check_constraints;
- return td->check_constraints(td, sptr, ctfailcb, app_key);
-}
-
-/*
- * This type is implemented using OCTET_STRING,
- * so here we adjust the DEF accordingly.
- */
-static void
-Opaque_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
- td->free_struct = asn_DEF_OCTET_STRING.free_struct;
- td->print_struct = asn_DEF_OCTET_STRING.print_struct;
- td->ber_decoder = asn_DEF_OCTET_STRING.ber_decoder;
- td->der_encoder = asn_DEF_OCTET_STRING.der_encoder;
- td->xer_decoder = asn_DEF_OCTET_STRING.xer_decoder;
- td->xer_encoder = asn_DEF_OCTET_STRING.xer_encoder;
- td->uper_decoder = asn_DEF_OCTET_STRING.uper_decoder;
- td->uper_encoder = asn_DEF_OCTET_STRING.uper_encoder;
- if(!td->per_constraints)
- td->per_constraints = asn_DEF_OCTET_STRING.per_constraints;
- td->elements = asn_DEF_OCTET_STRING.elements;
- td->elements_count = asn_DEF_OCTET_STRING.elements_count;
- td->specifics = asn_DEF_OCTET_STRING.specifics;
-}
-
-void
-Opaque_free(asn_TYPE_descriptor_t *td,
- void *struct_ptr, int contents_only) {
- Opaque_1_inherit_TYPE_descriptor(td);
- td->free_struct(td, struct_ptr, contents_only);
-}
-
-int
-Opaque_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
- int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
- Opaque_1_inherit_TYPE_descriptor(td);
- return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
-}
-
-asn_dec_rval_t
-Opaque_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
- void **structure, const void *bufptr, size_t size, int tag_mode) {
- Opaque_1_inherit_TYPE_descriptor(td);
- return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode);
-}
-
-asn_enc_rval_t
-Opaque_encode_der(asn_TYPE_descriptor_t *td,
- void *structure, int tag_mode, ber_tlv_tag_t tag,
- asn_app_consume_bytes_f *cb, void *app_key) {
- Opaque_1_inherit_TYPE_descriptor(td);
- return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
-}
-
-asn_dec_rval_t
-Opaque_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
- void **structure, const char *opt_mname, const void *bufptr, size_t size) {
- Opaque_1_inherit_TYPE_descriptor(td);
- return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size);
-}
-
-asn_enc_rval_t
-Opaque_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
- int ilevel, enum xer_encoder_flags_e flags,
- asn_app_consume_bytes_f *cb, void *app_key) {
- Opaque_1_inherit_TYPE_descriptor(td);
- return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
-}
-
-static ber_tlv_tag_t asn_DEF_Opaque_tags_1[] = {
- (ASN_TAG_CLASS_APPLICATION | (4 << 2)),
- (ASN_TAG_CLASS_UNIVERSAL | (4 << 2))
-};
-asn_TYPE_descriptor_t asn_DEF_Opaque = {
- "Opaque",
- "Opaque",
- Opaque_free,
- Opaque_print,
- Opaque_constraint,
- Opaque_decode_ber,
- Opaque_encode_der,
- Opaque_decode_xer,
- Opaque_encode_xer,
- 0, 0, /* No PER support, use "-gen-PER" to enable */
- 0, /* Use generic outmost tag fetcher */
- asn_DEF_Opaque_tags_1,
- sizeof(asn_DEF_Opaque_tags_1)
- /sizeof(asn_DEF_Opaque_tags_1[0]) - 1, /* 1 */
- asn_DEF_Opaque_tags_1, /* Same as above */
- sizeof(asn_DEF_Opaque_tags_1)
- /sizeof(asn_DEF_Opaque_tags_1[0]), /* 2 */
- 0, /* No PER visible constraints */
- 0, 0, /* No members */
- 0 /* No specifics */
-};
-
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1155-SMI"
- * found in "RFC1155-SMI.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#ifndef _Opaque_H_
-#define _Opaque_H_
-
-
-#include <asn_application.h>
-
-/* Including external dependencies */
-#include <OCTET_STRING.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Opaque */
-typedef OCTET_STRING_t Opaque_t;
-
-/* Implementation */
-extern asn_TYPE_descriptor_t asn_DEF_Opaque;
-asn_struct_free_f Opaque_free;
-asn_struct_print_f Opaque_print;
-asn_constr_check_f Opaque_constraint;
-ber_type_decoder_f Opaque_decode_ber;
-der_type_encoder_f Opaque_encode_der;
-xer_type_decoder_f Opaque_decode_xer;
-xer_type_encoder_f Opaque_encode_xer;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _Opaque_H_ */
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "SMUX"
- * found in "SMUX.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#include <asn_internal.h>
-
-#include "OpenPDU.h"
-
-static asn_TYPE_member_t asn_MBR_OpenPDU_1[] = {
- { ATF_NOFLAGS, 0, offsetof(struct OpenPDU, choice.simple),
- (ASN_TAG_CLASS_APPLICATION | (0 << 2)),
- 0,
- &asn_DEF_SimpleOpen,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "simple"
- },
-};
-static asn_TYPE_tag2member_t asn_MAP_OpenPDU_tag2el_1[] = {
- { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 0, 0, 0 } /* simple at 52 */
-};
-static asn_CHOICE_specifics_t asn_SPC_OpenPDU_specs_1 = {
- sizeof(struct OpenPDU),
- offsetof(struct OpenPDU, _asn_ctx),
- offsetof(struct OpenPDU, present),
- sizeof(((struct OpenPDU *)0)->present),
- asn_MAP_OpenPDU_tag2el_1,
- 1, /* Count of tags in the map */
- 0,
- -1 /* Extensions start */
-};
-asn_TYPE_descriptor_t asn_DEF_OpenPDU = {
- "OpenPDU",
- "OpenPDU",
- CHOICE_free,
- CHOICE_print,
- CHOICE_constraint,
- CHOICE_decode_ber,
- CHOICE_encode_der,
- CHOICE_decode_xer,
- CHOICE_encode_xer,
- 0, 0, /* No PER support, use "-gen-PER" to enable */
- CHOICE_outmost_tag,
- 0, /* No effective tags (pointer) */
- 0, /* No effective tags (count) */
- 0, /* No tags (pointer) */
- 0, /* No tags (count) */
- 0, /* No PER visible constraints */
- asn_MBR_OpenPDU_1,
- 1, /* Elements count */
- &asn_SPC_OpenPDU_specs_1 /* Additional specs */
-};
-
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "SMUX"
- * found in "SMUX.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#ifndef _OpenPDU_H_
-#define _OpenPDU_H_
-
-
-#include <asn_application.h>
-
-/* Including external dependencies */
-#include "SimpleOpen.h"
-#include <constr_CHOICE.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Dependencies */
-typedef enum OpenPDU_PR {
- OpenPDU_PR_NOTHING, /* No components present */
- OpenPDU_PR_simple
-} OpenPDU_PR;
-
-/* OpenPDU */
-typedef struct OpenPDU {
- OpenPDU_PR present;
- union OpenPDU_u {
- SimpleOpen_t simple;
- } choice;
-
- /* Context for parsing across buffer boundaries */
- asn_struct_ctx_t _asn_ctx;
-} OpenPDU_t;
-
-/* Implementation */
-extern asn_TYPE_descriptor_t asn_DEF_OpenPDU;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _OpenPDU_H_ */
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1157-SNMP"
- * found in "RFC1157-SNMP.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#include <asn_internal.h>
-
-#include "PDU.h"
-
-static asn_TYPE_member_t asn_MBR_PDU_1[] = {
- { ATF_NOFLAGS, 0, offsetof(struct PDU, request_id),
- (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
- 0,
- &asn_DEF_INTEGER,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "request-id"
- },
- { ATF_NOFLAGS, 0, offsetof(struct PDU, error_status),
- (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
- 0,
- &asn_DEF_INTEGER,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "error-status"
- },
- { ATF_NOFLAGS, 0, offsetof(struct PDU, error_index),
- (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
- 0,
- &asn_DEF_INTEGER,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "error-index"
- },
- { ATF_NOFLAGS, 0, offsetof(struct PDU, variable_bindings),
- (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)),
- 0,
- &asn_DEF_VarBindList,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "variable-bindings"
- },
-};
-static ber_tlv_tag_t asn_DEF_PDU_tags_1[] = {
- (ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
-};
-static asn_TYPE_tag2member_t asn_MAP_PDU_tag2el_1[] = {
- { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 2 }, /* request-id at 73 */
- { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 1, -1, 1 }, /* error-status at 77 */
- { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 2, -2, 0 }, /* error-index at 86 */
- { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)), 3, 0, 0 } /* variable-bindings at 90 */
-};
-static asn_SEQUENCE_specifics_t asn_SPC_PDU_specs_1 = {
- sizeof(struct PDU),
- offsetof(struct PDU, _asn_ctx),
- asn_MAP_PDU_tag2el_1,
- 4, /* Count of tags in the map */
- 0, 0, 0, /* Optional elements (not needed) */
- -1, /* Start extensions */
- -1 /* Stop extensions */
-};
-asn_TYPE_descriptor_t asn_DEF_PDU = {
- "PDU",
- "PDU",
- SEQUENCE_free,
- SEQUENCE_print,
- SEQUENCE_constraint,
- SEQUENCE_decode_ber,
- SEQUENCE_encode_der,
- SEQUENCE_decode_xer,
- SEQUENCE_encode_xer,
- 0, 0, /* No PER support, use "-gen-PER" to enable */
- 0, /* Use generic outmost tag fetcher */
- asn_DEF_PDU_tags_1,
- sizeof(asn_DEF_PDU_tags_1)
- /sizeof(asn_DEF_PDU_tags_1[0]), /* 1 */
- asn_DEF_PDU_tags_1, /* Same as above */
- sizeof(asn_DEF_PDU_tags_1)
- /sizeof(asn_DEF_PDU_tags_1[0]), /* 1 */
- 0, /* No PER visible constraints */
- asn_MBR_PDU_1,
- 4, /* Elements count */
- &asn_SPC_PDU_specs_1 /* Additional specs */
-};
-
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1157-SNMP"
- * found in "RFC1157-SNMP.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#ifndef _PDU_H_
-#define _PDU_H_
-
-
-#include <asn_application.h>
-
-/* Including external dependencies */
-#include <INTEGER.h>
-#include "VarBindList.h"
-#include <constr_SEQUENCE.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Dependencies */
-typedef enum PDU__error_status {
- PDU__error_status_noError = 0,
- PDU__error_status_tooBig = 1,
- PDU__error_status_noSuchName = 2,
- PDU__error_status_badValue = 3,
- PDU__error_status_readOnly = 4,
- PDU__error_status_genErr = 5
-} e_PDU__error_status;
-
-/* PDU */
-typedef struct PDU {
- INTEGER_t request_id;
- INTEGER_t error_status;
- INTEGER_t error_index;
- VarBindList_t variable_bindings;
-
- /* Context for parsing across buffer boundaries */
- asn_struct_ctx_t _asn_ctx;
-} PDU_t;
-
-/* Implementation */
-extern asn_TYPE_descriptor_t asn_DEF_PDU;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PDU_H_ */
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1157-SNMP"
- * found in "RFC1157-SNMP.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#include <asn_internal.h>
-
-#include "PDUs.h"
-
-static asn_TYPE_member_t asn_MBR_PDUs_1[] = {
- { ATF_NOFLAGS, 0, offsetof(struct PDUs, choice.get_request),
- (ASN_TAG_CLASS_CONTEXT | (0 << 2)),
- 0,
- &asn_DEF_GetRequest_PDU,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "get-request"
- },
- { ATF_NOFLAGS, 0, offsetof(struct PDUs, choice.get_next_request),
- (ASN_TAG_CLASS_CONTEXT | (1 << 2)),
- 0,
- &asn_DEF_GetNextRequest_PDU,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "get-next-request"
- },
- { ATF_NOFLAGS, 0, offsetof(struct PDUs, choice.get_response),
- (ASN_TAG_CLASS_CONTEXT | (2 << 2)),
- 0,
- &asn_DEF_GetResponse_PDU,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "get-response"
- },
- { ATF_NOFLAGS, 0, offsetof(struct PDUs, choice.set_request),
- (ASN_TAG_CLASS_CONTEXT | (3 << 2)),
- 0,
- &asn_DEF_SetRequest_PDU,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "set-request"
- },
- { ATF_NOFLAGS, 0, offsetof(struct PDUs, choice.trap),
- (ASN_TAG_CLASS_CONTEXT | (4 << 2)),
- 0,
- &asn_DEF_Trap_PDU,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "trap"
- },
-};
-static asn_TYPE_tag2member_t asn_MAP_PDUs_tag2el_1[] = {
- { (ASN_TAG_CLASS_CONTEXT | (0 << 2)), 0, 0, 0 }, /* get-request at 34 */
- { (ASN_TAG_CLASS_CONTEXT | (1 << 2)), 1, 0, 0 }, /* get-next-request at 37 */
- { (ASN_TAG_CLASS_CONTEXT | (2 << 2)), 2, 0, 0 }, /* get-response at 40 */
- { (ASN_TAG_CLASS_CONTEXT | (3 << 2)), 3, 0, 0 }, /* set-request at 43 */
- { (ASN_TAG_CLASS_CONTEXT | (4 << 2)), 4, 0, 0 } /* trap at 47 */
-};
-static asn_CHOICE_specifics_t asn_SPC_PDUs_specs_1 = {
- sizeof(struct PDUs),
- offsetof(struct PDUs, _asn_ctx),
- offsetof(struct PDUs, present),
- sizeof(((struct PDUs *)0)->present),
- asn_MAP_PDUs_tag2el_1,
- 5, /* Count of tags in the map */
- 0,
- -1 /* Extensions start */
-};
-asn_TYPE_descriptor_t asn_DEF_PDUs = {
- "PDUs",
- "PDUs",
- CHOICE_free,
- CHOICE_print,
- CHOICE_constraint,
- CHOICE_decode_ber,
- CHOICE_encode_der,
- CHOICE_decode_xer,
- CHOICE_encode_xer,
- 0, 0, /* No PER support, use "-gen-PER" to enable */
- CHOICE_outmost_tag,
- 0, /* No effective tags (pointer) */
- 0, /* No effective tags (count) */
- 0, /* No tags (pointer) */
- 0, /* No tags (count) */
- 0, /* No PER visible constraints */
- asn_MBR_PDUs_1,
- 5, /* Elements count */
- &asn_SPC_PDUs_specs_1 /* Additional specs */
-};
-
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1157-SNMP"
- * found in "RFC1157-SNMP.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#ifndef _PDUs_H_
-#define _PDUs_H_
-
-
-#include <asn_application.h>
-
-/* Including external dependencies */
-#include "GetRequest-PDU.h"
-#include "GetNextRequest-PDU.h"
-#include "GetResponse-PDU.h"
-#include "SetRequest-PDU.h"
-#include "Trap-PDU.h"
-#include <constr_CHOICE.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Dependencies */
-typedef enum PDUs_PR {
- PDUs_PR_NOTHING, /* No components present */
- PDUs_PR_get_request,
- PDUs_PR_get_next_request,
- PDUs_PR_get_response,
- PDUs_PR_set_request,
- PDUs_PR_trap
-} PDUs_PR;
-
-/* PDUs */
-typedef struct PDUs {
- PDUs_PR present;
- union PDUs_u {
- GetRequest_PDU_t get_request;
- GetNextRequest_PDU_t get_next_request;
- GetResponse_PDU_t get_response;
- SetRequest_PDU_t set_request;
- Trap_PDU_t trap;
- } choice;
-
- /* Context for parsing across buffer boundaries */
- asn_struct_ctx_t _asn_ctx;
-} PDUs_t;
-
-/* Implementation */
-extern asn_TYPE_descriptor_t asn_DEF_PDUs;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PDUs_H_ */
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1213-MIB"
- * found in "RFC1213-MIB.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#include <asn_internal.h>
-
-#include "PhysAddress.h"
-
-int
-PhysAddress_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
- asn_app_constraint_failed_f *ctfailcb, void *app_key) {
- /* Replace with underlying type checker */
- td->check_constraints = asn_DEF_OCTET_STRING.check_constraints;
- return td->check_constraints(td, sptr, ctfailcb, app_key);
-}
-
-/*
- * This type is implemented using OCTET_STRING,
- * so here we adjust the DEF accordingly.
- */
-static void
-PhysAddress_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
- td->free_struct = asn_DEF_OCTET_STRING.free_struct;
- td->print_struct = asn_DEF_OCTET_STRING.print_struct;
- td->ber_decoder = asn_DEF_OCTET_STRING.ber_decoder;
- td->der_encoder = asn_DEF_OCTET_STRING.der_encoder;
- td->xer_decoder = asn_DEF_OCTET_STRING.xer_decoder;
- td->xer_encoder = asn_DEF_OCTET_STRING.xer_encoder;
- td->uper_decoder = asn_DEF_OCTET_STRING.uper_decoder;
- td->uper_encoder = asn_DEF_OCTET_STRING.uper_encoder;
- if(!td->per_constraints)
- td->per_constraints = asn_DEF_OCTET_STRING.per_constraints;
- td->elements = asn_DEF_OCTET_STRING.elements;
- td->elements_count = asn_DEF_OCTET_STRING.elements_count;
- td->specifics = asn_DEF_OCTET_STRING.specifics;
-}
-
-void
-PhysAddress_free(asn_TYPE_descriptor_t *td,
- void *struct_ptr, int contents_only) {
- PhysAddress_1_inherit_TYPE_descriptor(td);
- td->free_struct(td, struct_ptr, contents_only);
-}
-
-int
-PhysAddress_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
- int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
- PhysAddress_1_inherit_TYPE_descriptor(td);
- return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
-}
-
-asn_dec_rval_t
-PhysAddress_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
- void **structure, const void *bufptr, size_t size, int tag_mode) {
- PhysAddress_1_inherit_TYPE_descriptor(td);
- return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode);
-}
-
-asn_enc_rval_t
-PhysAddress_encode_der(asn_TYPE_descriptor_t *td,
- void *structure, int tag_mode, ber_tlv_tag_t tag,
- asn_app_consume_bytes_f *cb, void *app_key) {
- PhysAddress_1_inherit_TYPE_descriptor(td);
- return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
-}
-
-asn_dec_rval_t
-PhysAddress_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
- void **structure, const char *opt_mname, const void *bufptr, size_t size) {
- PhysAddress_1_inherit_TYPE_descriptor(td);
- return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size);
-}
-
-asn_enc_rval_t
-PhysAddress_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
- int ilevel, enum xer_encoder_flags_e flags,
- asn_app_consume_bytes_f *cb, void *app_key) {
- PhysAddress_1_inherit_TYPE_descriptor(td);
- return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
-}
-
-static ber_tlv_tag_t asn_DEF_PhysAddress_tags_1[] = {
- (ASN_TAG_CLASS_UNIVERSAL | (4 << 2))
-};
-asn_TYPE_descriptor_t asn_DEF_PhysAddress = {
- "PhysAddress",
- "PhysAddress",
- PhysAddress_free,
- PhysAddress_print,
- PhysAddress_constraint,
- PhysAddress_decode_ber,
- PhysAddress_encode_der,
- PhysAddress_decode_xer,
- PhysAddress_encode_xer,
- 0, 0, /* No PER support, use "-gen-PER" to enable */
- 0, /* Use generic outmost tag fetcher */
- asn_DEF_PhysAddress_tags_1,
- sizeof(asn_DEF_PhysAddress_tags_1)
- /sizeof(asn_DEF_PhysAddress_tags_1[0]), /* 1 */
- asn_DEF_PhysAddress_tags_1, /* Same as above */
- sizeof(asn_DEF_PhysAddress_tags_1)
- /sizeof(asn_DEF_PhysAddress_tags_1[0]), /* 1 */
- 0, /* No PER visible constraints */
- 0, 0, /* No members */
- 0 /* No specifics */
-};
-
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1213-MIB"
- * found in "RFC1213-MIB.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#ifndef _PhysAddress_H_
-#define _PhysAddress_H_
-
-
-#include <asn_application.h>
-
-/* Including external dependencies */
-#include <OCTET_STRING.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* PhysAddress */
-typedef OCTET_STRING_t PhysAddress_t;
-
-/* Implementation */
-extern asn_TYPE_descriptor_t asn_DEF_PhysAddress;
-asn_struct_free_f PhysAddress_free;
-asn_struct_print_f PhysAddress_print;
-asn_constr_check_f PhysAddress_constraint;
-ber_type_decoder_f PhysAddress_decode_ber;
-der_type_encoder_f PhysAddress_encode_der;
-xer_type_decoder_f PhysAddress_decode_xer;
-xer_type_encoder_f PhysAddress_encode_xer;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PhysAddress_H_ */
+++ /dev/null
-
--- WinAgents MIB Extraction Wizard\r
--- Extracted from rfc1155.txt 17.03.2005 16:16:50\r
-\r
-RFC1155-SMI DEFINITIONS ::= BEGIN\r
-\r
---EXPORTS EVERYTHING\r
--- internet, directory, mgmt,\r
--- experimental, private, enterprises,\r
--- OBJECT-TYPE, ObjectName, ObjectSyntax, SimpleSyntax,\r
--- ApplicationSyntax, NetworkAddress, IpAddress,\r
--- Counter, Gauge, TimeTicks, Opaque;\r
-\r
- -- the path to the root\r
-\r
- internet OBJECT IDENTIFIER ::= { iso org(3) dod(6) 1 }\r
-\r
- directory OBJECT IDENTIFIER ::= { internet 1 }\r
-\r
- mgmt OBJECT IDENTIFIER ::= { internet 2 }\r
-\r
- experimental OBJECT IDENTIFIER ::= { internet 3 }\r
-\r
- private OBJECT IDENTIFIER ::= { internet 4 }\r
- enterprises OBJECT IDENTIFIER ::= { private 1 }\r
-\r
-\r
- -- definition of object types\r
-\r
--- MIB Extraction: All MACRO definitions are predefined by compiler\r
--- commented by MIB Extraction: OBJECT-TYPE MACRO ::=\r
--- commented by MIB Extraction: BEGIN\r
--- commented by MIB Extraction: TYPE NOTATION ::= "SYNTAX" type (TYPE ObjectSyntax)\r
--- commented by MIB Extraction: "ACCESS" Access\r
--- commented by MIB Extraction: "STATUS" Status\r
--- commented by MIB Extraction: VALUE NOTATION ::= value (VALUE ObjectName)\r
--- commented by MIB Extraction: \r
--- commented by MIB Extraction: Access ::= "read-only"\r
--- commented by MIB Extraction: | "read-write"\r
--- commented by MIB Extraction: | "write-only"\r
--- commented by MIB Extraction: | "not-accessible"\r
--- commented by MIB Extraction: Status ::= "mandatory"\r
--- commented by MIB Extraction: | "optional"\r
--- commented by MIB Extraction: | "obsolete"\r
--- commented by MIB Extraction: END\r
-\r
- -- names of objects in the MIB\r
-\r
- ObjectName ::=\r
- OBJECT IDENTIFIER\r
-\r
-\r
- -- syntax of objects in the MIB\r
-\r
- ObjectSyntax ::=\r
- CHOICE {\r
- simple\r
- SimpleSyntax,\r
-\r
- -- note that simple SEQUENCEs are not directly\r
- -- mentioned here to keep things simple (i.e.,\r
- -- prevent mis-use). However, application-wide\r
- -- types which are IMPLICITly encoded simple\r
- -- SEQUENCEs may appear in the following CHOICE\r
-\r
- application-wide\r
- ApplicationSyntax\r
- }\r
-\r
- SimpleSyntax ::=\r
- CHOICE {\r
- number\r
- INTEGER,\r
-\r
- string\r
- OCTET STRING,\r
-\r
- object\r
- OBJECT IDENTIFIER,\r
-\r
- empty\r
- NULL\r
- }\r
-\r
- ApplicationSyntax ::=\r
- CHOICE {\r
- address\r
- NetworkAddress,\r
-\r
- counter\r
- Counter,\r
-\r
- gauge\r
- Gauge,\r
-\r
- ticks\r
- TimeTicks,\r
-\r
- arbitrary\r
- Opaque\r
-\r
- -- other application-wide types, as they are\r
- -- defined, will be added here\r
- }\r
-\r
-\r
- -- application-wide types\r
-\r
- NetworkAddress ::=\r
- CHOICE {\r
- internet\r
- IpAddress\r
- }\r
-\r
- IpAddress ::=\r
- [APPLICATION 0] -- in network-byte order\r
- IMPLICIT OCTET STRING (SIZE (4))\r
-\r
- Counter ::=\r
- [APPLICATION 1]\r
- IMPLICIT INTEGER (0..4294967295)\r
-\r
- Gauge ::=\r
- [APPLICATION 2]\r
- IMPLICIT INTEGER (0..4294967295)\r
-\r
- TimeTicks ::=\r
- [APPLICATION 3]\r
- IMPLICIT INTEGER (0..4294967295)\r
-\r
- Opaque ::=\r
- [APPLICATION 4] -- arbitrary ASN.1 value,\r
- IMPLICIT OCTET STRING -- "double-wrapped"\r
-\r
- END\r
+++ /dev/null
-
--- WinAgents MIB Extraction Wizard\r
--- Extracted from rfc1157.txt 16.03.2005 20:20:14\r
-\r
-RFC1157-SNMP DEFINITIONS ::= BEGIN\r
-\r
- IMPORTS\r
- ObjectName, ObjectSyntax, NetworkAddress, IpAddress, TimeTicks\r
- FROM RFC1155-SMI;\r
-\r
-\r
- -- top-level message\r
-\r
- Message ::=\r
- SEQUENCE {\r
- version -- version-1 for this RFC\r
- INTEGER {\r
- version-1(0)\r
- },\r
-\r
- community -- community name\r
- OCTET STRING,\r
-\r
- data -- e.g., PDUs if trivial\r
- ANY -- authentication is being used\r
- }\r
-\r
-\r
- -- protocol data units\r
-\r
- PDUs ::=\r
- CHOICE {\r
- get-request\r
- GetRequest-PDU,\r
-\r
- get-next-request\r
- GetNextRequest-PDU,\r
-\r
- get-response\r
- GetResponse-PDU,\r
-\r
- set-request\r
- SetRequest-PDU,\r
-\r
- trap\r
- Trap-PDU\r
- }\r
-\r
-\r
-\r
-\r
- -- PDUs\r
-\r
- GetRequest-PDU ::=\r
- [0]\r
- IMPLICIT PDU\r
-\r
- GetNextRequest-PDU ::=\r
- [1]\r
- IMPLICIT PDU\r
-\r
- GetResponse-PDU ::=\r
- [2]\r
- IMPLICIT PDU\r
-\r
- SetRequest-PDU ::=\r
- [3]\r
- IMPLICIT PDU\r
-\r
- PDU ::=\r
- SEQUENCE {\r
- request-id\r
- INTEGER,\r
-\r
- error-status -- sometimes ignored\r
- INTEGER {\r
- noError(0),\r
- tooBig(1),\r
- noSuchName(2),\r
- badValue(3),\r
- readOnly(4),\r
- genErr(5)\r
- },\r
-\r
- error-index -- sometimes ignored\r
- INTEGER,\r
-\r
- variable-bindings -- values are sometimes ignored\r
- VarBindList\r
- }\r
-\r
- Trap-PDU ::=\r
- [4]\r
- IMPLICIT SEQUENCE {\r
- enterprise -- type of object generating\r
- -- trap, see sysObjectID in [5]\r
-\r
-\r
- OBJECT IDENTIFIER,\r
-\r
- agent-addr -- address of object generating\r
- NetworkAddress, -- trap\r
-\r
- generic-trap -- generic trap type\r
- INTEGER {\r
- coldStart(0),\r
- warmStart(1),\r
- linkDown(2),\r
- linkUp(3),\r
- authenticationFailure(4),\r
- egpNeighborLoss(5),\r
- enterpriseSpecific(6)\r
- },\r
-\r
- specific-trap -- specific code, present even\r
- INTEGER, -- if generic-trap is not\r
- -- enterpriseSpecific\r
-\r
- time-stamp -- time elapsed between the last\r
- TimeTicks, -- (re)initialization of the network\r
- -- entity and the generation of the trap\r
-\r
- variable-bindings -- "interesting" information\r
- VarBindList\r
- }\r
-\r
-\r
- -- variable bindings\r
-\r
- VarBind ::=\r
- SEQUENCE {\r
- name\r
- ObjectName,\r
-\r
- value\r
- ObjectSyntax\r
- }\r
-\r
- VarBindList ::=\r
- SEQUENCE OF\r
- VarBind\r
-\r
- END
\ No newline at end of file
+++ /dev/null
-
--- WinAgents MIB Extraction Wizard\r
--- Extracted from rfc1213.txt 16.03.2005 20:20:14\r
-\r
-RFC1213-MIB DEFINITIONS ::= BEGIN\r
-\r
-IMPORTS\r
- mgmt, NetworkAddress, IpAddress, Counter, Gauge,\r
- TimeTicks\r
- FROM RFC1155-SMI\r
- OBJECT-TYPE\r
- FROM RFC-1212;\r
-\r
--- This MIB module uses the extended OBJECT-TYPE macro as\r
--- defined in [14];\r
-\r
-\r
--- MIB-II (same prefix as MIB-I)\r
-\r
-mib-2 OBJECT IDENTIFIER ::= { mgmt 1 }\r
-\r
--- textual conventions\r
-\r
-DisplayString ::=\r
- OCTET STRING\r
--- This data type is used to model textual information taken\r
--- from the NVT ASCII character set. By convention, objects\r
--- with this syntax are declared as having\r
-\r
---\r
--- SIZE (0..255)\r
-\r
-PhysAddress ::=\r
- OCTET STRING\r
--- This data type is used to model media addresses. For many\r
--- types of media, this will be in a binary representation.\r
--- For example, an ethernet address would be represented as\r
--- a string of 6 octets.\r
-\r
-\r
--- groups in MIB-II\r
-\r
-system OBJECT IDENTIFIER ::= { mib-2 1 }\r
-\r
-interfaces OBJECT IDENTIFIER ::= { mib-2 2 }\r
-\r
-at OBJECT IDENTIFIER ::= { mib-2 3 }\r
-\r
-ip OBJECT IDENTIFIER ::= { mib-2 4 }\r
-\r
-icmp OBJECT IDENTIFIER ::= { mib-2 5 }\r
-\r
-tcp OBJECT IDENTIFIER ::= { mib-2 6 }\r
-\r
-udp OBJECT IDENTIFIER ::= { mib-2 7 }\r
-\r
-egp OBJECT IDENTIFIER ::= { mib-2 8 }\r
-\r
--- historical (some say hysterical)\r
--- cmot OBJECT IDENTIFIER ::= { mib-2 9 }\r
-\r
-transmission OBJECT IDENTIFIER ::= { mib-2 10 }\r
-\r
-snmp OBJECT IDENTIFIER ::= { mib-2 11 }\r
-\r
-\r
--- the System group\r
-\r
--- Implementation of the System group is mandatory for all\r
--- systems. If an agent is not configured to have a value\r
--- for any of these variables, a string of length 0 is\r
--- returned.\r
-\r
-\r
-IfEntry ::=\r
- SEQUENCE {\r
- ifIndex\r
- INTEGER,\r
-\r
- ifDescr\r
- DisplayString,\r
- ifType\r
- INTEGER,\r
- ifMtu\r
- INTEGER,\r
- ifSpeed\r
- Gauge,\r
- ifPhysAddress\r
- PhysAddress,\r
- ifAdminStatus\r
- INTEGER,\r
- ifOperStatus\r
- INTEGER,\r
- ifLastChange\r
- TimeTicks,\r
- ifInOctets\r
- Counter,\r
- ifInUcastPkts\r
- Counter,\r
- ifInNUcastPkts\r
- Counter,\r
- ifInDiscards\r
- Counter,\r
- ifInErrors\r
- Counter,\r
- ifInUnknownProtos\r
- Counter,\r
- ifOutOctets\r
- Counter,\r
- ifOutUcastPkts\r
- Counter,\r
- ifOutNUcastPkts\r
- Counter,\r
- ifOutDiscards\r
- Counter,\r
- ifOutErrors\r
- Counter,\r
- ifOutQLen\r
- Gauge,\r
- ifSpecific\r
- OBJECT IDENTIFIER\r
- }\r
-\r
-\r
--- the Address Translation group\r
-\r
--- Implementation of the Address Translation group is\r
--- mandatory for all systems. Note however that this group\r
--- is deprecated by MIB-II. That is, it is being included\r
-\r
--- solely for compatibility with MIB-I nodes, and will most\r
--- likely be excluded from MIB-III nodes. From MIB-II and\r
--- onwards, each network protocol group contains its own\r
--- address translation tables.\r
-\r
--- The Address Translation group contains one table which is\r
--- the union across all interfaces of the translation tables\r
--- for converting a NetworkAddress (e.g., an IP address) into\r
--- a subnetwork-specific address. For lack of a better term,\r
--- this document refers to such a subnetwork-specific address\r
--- as a `physical' address.\r
-\r
--- Examples of such translation tables are: for broadcast\r
--- media where ARP is in use, the translation table is\r
--- equivalent to the ARP cache; or, on an X.25 network where\r
--- non-algorithmic translation to X.121 addresses is\r
--- required, the translation table contains the\r
--- NetworkAddress to X.121 address equivalences.\r
-\r
-\r
-AtEntry ::=\r
- SEQUENCE {\r
- atIfIndex\r
- INTEGER,\r
-\r
- atPhysAddress\r
- PhysAddress,\r
- atNetAddress\r
- NetworkAddress\r
- }\r
-\r
-\r
-\r
-\r
-\r
--- the IP address table\r
-\r
--- The IP address table contains this entity's IP addressing\r
--- information.\r
-\r
-\r
-IpAddrEntry ::=\r
- SEQUENCE {\r
- ipAdEntAddr\r
- IpAddress,\r
- ipAdEntIfIndex\r
- INTEGER,\r
- ipAdEntNetMask\r
- IpAddress,\r
- ipAdEntBcastAddr\r
- INTEGER,\r
- ipAdEntReasmMaxSize\r
- INTEGER (0..65535)\r
- }\r
-\r
-\r
-IpRouteEntry ::=\r
- SEQUENCE {\r
- ipRouteDest\r
- IpAddress,\r
- ipRouteIfIndex\r
- INTEGER,\r
- ipRouteMetric1\r
- INTEGER,\r
- ipRouteMetric2\r
- INTEGER,\r
- ipRouteMetric3\r
- INTEGER,\r
- ipRouteMetric4\r
- INTEGER,\r
- ipRouteNextHop\r
- IpAddress,\r
- ipRouteType\r
- INTEGER,\r
- ipRouteProto\r
- INTEGER,\r
- ipRouteAge\r
- INTEGER,\r
- ipRouteMask\r
- IpAddress,\r
- ipRouteMetric5\r
- INTEGER,\r
-\r
- ipRouteInfo\r
- OBJECT IDENTIFIER\r
- }\r
-\r
-\r
-IpNetToMediaEntry ::=\r
- SEQUENCE {\r
- ipNetToMediaIfIndex\r
- INTEGER,\r
- ipNetToMediaPhysAddress\r
- PhysAddress,\r
- ipNetToMediaNetAddress\r
- IpAddress,\r
- ipNetToMediaType\r
- INTEGER\r
- }\r
-\r
-\r
-\r
-TcpConnEntry ::=\r
- SEQUENCE {\r
- tcpConnState\r
- INTEGER,\r
- tcpConnLocalAddress\r
- IpAddress,\r
- tcpConnLocalPort\r
- INTEGER (0..65535),\r
- tcpConnRemAddress\r
- IpAddress,\r
- tcpConnRemPort\r
- INTEGER (0..65535)\r
- }\r
-\r
-\r
-UdpEntry ::=\r
- SEQUENCE {\r
- udpLocalAddress\r
- IpAddress,\r
- udpLocalPort\r
- INTEGER (0..65535)\r
- }\r
-\r
-\r
-\r
--- the EGP Neighbor table\r
-\r
--- The EGP neighbor table contains information about this\r
--- entity's EGP neighbors.\r
-\r
-\r
-EgpNeighEntry ::=\r
- SEQUENCE {\r
- egpNeighState\r
- INTEGER,\r
- egpNeighAddr\r
- IpAddress,\r
- egpNeighAs\r
- INTEGER,\r
- egpNeighInMsgs\r
- Counter,\r
- egpNeighInErrs\r
- Counter,\r
- egpNeighOutMsgs\r
- Counter,\r
- egpNeighOutErrs\r
- Counter,\r
-\r
- egpNeighInErrMsgs\r
- Counter,\r
- egpNeighOutErrMsgs\r
- Counter,\r
- egpNeighStateUps\r
- Counter,\r
- egpNeighStateDowns\r
- Counter,\r
- egpNeighIntervalHello\r
- INTEGER,\r
- egpNeighIntervalPoll\r
- INTEGER,\r
- egpNeighMode\r
- INTEGER,\r
- egpNeighEventTrigger\r
- INTEGER\r
- }\r
-\r
-\r
-\r
--- the Transmission group\r
-\r
--- Based on the transmission media underlying each interface\r
--- on a system, the corresponding portion of the Transmission\r
--- group is mandatory for that system.\r
-\r
--- When Internet-standard definitions for managing\r
--- transmission media are defined, the transmission group is\r
--- used to provide a prefix for the names of those objects.\r
-\r
--- Typically, such definitions reside in the experimental\r
--- portion of the MIB until they are "proven", then as a\r
--- part of the Internet standardization process, the\r
--- definitions are accordingly elevated and a new object\r
--- identifier, under the transmission group is defined. By\r
--- convention, the name assigned is:\r
---\r
--- type OBJECT IDENTIFIER ::= { transmission number }\r
---\r
--- where "type" is the symbolic value used for the media in\r
--- the ifType column of the ifTable object, and "number" is\r
--- the actual integer value corresponding to the symbol.\r
-\r
-\r
--- the SNMP group\r
-\r
--- Implementation of the SNMP group is mandatory for all\r
--- systems which support an SNMP protocol entity. Some of\r
--- the objects defined below will be zero-valued in those\r
--- SNMP implementations that are optimized to support only\r
--- those functions specific to either a management agent or\r
--- a management station. In particular, it should be\r
--- observed that the objects below refer to an SNMP entity,\r
--- and there may be several SNMP entities residing on a\r
--- managed node (e.g., if the node is hosting acting as\r
--- a management station).\r
-\r
-\r
-END\r
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "SMUX"
- * found in "SMUX.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#include <asn_internal.h>
-
-#include "RReqPDU.h"
-
-static int
-memb_priority_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr,
- asn_app_constraint_failed_f *ctfailcb, void *app_key) {
- long value;
-
- if(!sptr) {
- _ASN_CTFAIL(app_key, td, sptr,
- "%s: value not given (%s:%d)",
- td->name, __FILE__, __LINE__);
- return -1;
- }
-
- value = *(const long *)sptr;
-
- if((value >= -1 && value <= 2147483647)) {
- /* Constraint check succeeded */
- return 0;
- } else {
- _ASN_CTFAIL(app_key, td, sptr,
- "%s: constraint failed (%s:%d)",
- td->name, __FILE__, __LINE__);
- return -1;
- }
-}
-
-static asn_TYPE_member_t asn_MBR_RReqPDU_1[] = {
- { ATF_NOFLAGS, 0, offsetof(struct RReqPDU, subtree),
- (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)),
- 0,
- &asn_DEF_ObjectName,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "subtree"
- },
- { ATF_NOFLAGS, 0, offsetof(struct RReqPDU, priority),
- (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
- 0,
- &asn_DEF_NativeInteger,
- memb_priority_constraint_1,
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "priority"
- },
- { ATF_NOFLAGS, 0, offsetof(struct RReqPDU, operation),
- (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
- 0,
- &asn_DEF_INTEGER,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "operation"
- },
-};
-static ber_tlv_tag_t asn_DEF_RReqPDU_tags_1[] = {
- (ASN_TAG_CLASS_APPLICATION | (2 << 2)),
- (ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
-};
-static asn_TYPE_tag2member_t asn_MAP_RReqPDU_tag2el_1[] = {
- { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 1, 0, 1 }, /* priority at 96 */
- { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 2, -1, 0 }, /* operation at 101 */
- { (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)), 0, 0, 0 } /* subtree at 93 */
-};
-static asn_SEQUENCE_specifics_t asn_SPC_RReqPDU_specs_1 = {
- sizeof(struct RReqPDU),
- offsetof(struct RReqPDU, _asn_ctx),
- asn_MAP_RReqPDU_tag2el_1,
- 3, /* Count of tags in the map */
- 0, 0, 0, /* Optional elements (not needed) */
- -1, /* Start extensions */
- -1 /* Stop extensions */
-};
-asn_TYPE_descriptor_t asn_DEF_RReqPDU = {
- "RReqPDU",
- "RReqPDU",
- SEQUENCE_free,
- SEQUENCE_print,
- SEQUENCE_constraint,
- SEQUENCE_decode_ber,
- SEQUENCE_encode_der,
- SEQUENCE_decode_xer,
- SEQUENCE_encode_xer,
- 0, 0, /* No PER support, use "-gen-PER" to enable */
- 0, /* Use generic outmost tag fetcher */
- asn_DEF_RReqPDU_tags_1,
- sizeof(asn_DEF_RReqPDU_tags_1)
- /sizeof(asn_DEF_RReqPDU_tags_1[0]) - 1, /* 1 */
- asn_DEF_RReqPDU_tags_1, /* Same as above */
- sizeof(asn_DEF_RReqPDU_tags_1)
- /sizeof(asn_DEF_RReqPDU_tags_1[0]), /* 2 */
- 0, /* No PER visible constraints */
- asn_MBR_RReqPDU_1,
- 3, /* Elements count */
- &asn_SPC_RReqPDU_specs_1 /* Additional specs */
-};
-
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "SMUX"
- * found in "SMUX.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#ifndef _RReqPDU_H_
-#define _RReqPDU_H_
-
-
-#include <asn_application.h>
-
-/* Including external dependencies */
-#include "ObjectName.h"
-#include <NativeInteger.h>
-#include <INTEGER.h>
-#include <constr_SEQUENCE.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Dependencies */
-typedef enum RReqPDU__operation {
- RReqPDU__operation_delete = 0,
- RReqPDU__operation_readOnly = 1,
- RReqPDU__operation_readWrite = 2
-} e_RReqPDU__operation;
-
-/* RReqPDU */
-typedef struct RReqPDU {
- ObjectName_t subtree;
- long priority;
- INTEGER_t operation;
-
- /* Context for parsing across buffer boundaries */
- asn_struct_ctx_t _asn_ctx;
-} RReqPDU_t;
-
-/* Implementation */
-extern asn_TYPE_descriptor_t asn_DEF_RReqPDU;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _RReqPDU_H_ */
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "SMUX"
- * found in "SMUX.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#include <asn_internal.h>
-
-#include "RRspPDU.h"
-
-int
-RRspPDU_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
- asn_app_constraint_failed_f *ctfailcb, void *app_key) {
- /* Replace with underlying type checker */
- td->check_constraints = asn_DEF_INTEGER.check_constraints;
- return td->check_constraints(td, sptr, ctfailcb, app_key);
-}
-
-/*
- * This type is implemented using INTEGER,
- * so here we adjust the DEF accordingly.
- */
-static void
-RRspPDU_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
- td->free_struct = asn_DEF_INTEGER.free_struct;
- td->print_struct = asn_DEF_INTEGER.print_struct;
- td->ber_decoder = asn_DEF_INTEGER.ber_decoder;
- td->der_encoder = asn_DEF_INTEGER.der_encoder;
- td->xer_decoder = asn_DEF_INTEGER.xer_decoder;
- td->xer_encoder = asn_DEF_INTEGER.xer_encoder;
- td->uper_decoder = asn_DEF_INTEGER.uper_decoder;
- td->uper_encoder = asn_DEF_INTEGER.uper_encoder;
- if(!td->per_constraints)
- td->per_constraints = asn_DEF_INTEGER.per_constraints;
- td->elements = asn_DEF_INTEGER.elements;
- td->elements_count = asn_DEF_INTEGER.elements_count;
- td->specifics = asn_DEF_INTEGER.specifics;
-}
-
-void
-RRspPDU_free(asn_TYPE_descriptor_t *td,
- void *struct_ptr, int contents_only) {
- RRspPDU_1_inherit_TYPE_descriptor(td);
- td->free_struct(td, struct_ptr, contents_only);
-}
-
-int
-RRspPDU_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
- int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
- RRspPDU_1_inherit_TYPE_descriptor(td);
- return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
-}
-
-asn_dec_rval_t
-RRspPDU_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
- void **structure, const void *bufptr, size_t size, int tag_mode) {
- RRspPDU_1_inherit_TYPE_descriptor(td);
- return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode);
-}
-
-asn_enc_rval_t
-RRspPDU_encode_der(asn_TYPE_descriptor_t *td,
- void *structure, int tag_mode, ber_tlv_tag_t tag,
- asn_app_consume_bytes_f *cb, void *app_key) {
- RRspPDU_1_inherit_TYPE_descriptor(td);
- return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
-}
-
-asn_dec_rval_t
-RRspPDU_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
- void **structure, const char *opt_mname, const void *bufptr, size_t size) {
- RRspPDU_1_inherit_TYPE_descriptor(td);
- return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size);
-}
-
-asn_enc_rval_t
-RRspPDU_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
- int ilevel, enum xer_encoder_flags_e flags,
- asn_app_consume_bytes_f *cb, void *app_key) {
- RRspPDU_1_inherit_TYPE_descriptor(td);
- return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
-}
-
-static ber_tlv_tag_t asn_DEF_RRspPDU_tags_1[] = {
- (ASN_TAG_CLASS_APPLICATION | (3 << 2)),
- (ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
-};
-asn_TYPE_descriptor_t asn_DEF_RRspPDU = {
- "RRspPDU",
- "RRspPDU",
- RRspPDU_free,
- RRspPDU_print,
- RRspPDU_constraint,
- RRspPDU_decode_ber,
- RRspPDU_encode_der,
- RRspPDU_decode_xer,
- RRspPDU_encode_xer,
- 0, 0, /* No PER support, use "-gen-PER" to enable */
- 0, /* Use generic outmost tag fetcher */
- asn_DEF_RRspPDU_tags_1,
- sizeof(asn_DEF_RRspPDU_tags_1)
- /sizeof(asn_DEF_RRspPDU_tags_1[0]) - 1, /* 1 */
- asn_DEF_RRspPDU_tags_1, /* Same as above */
- sizeof(asn_DEF_RRspPDU_tags_1)
- /sizeof(asn_DEF_RRspPDU_tags_1[0]), /* 2 */
- 0, /* No PER visible constraints */
- 0, 0, /* Defined elsewhere */
- 0 /* No specifics */
-};
-
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "SMUX"
- * found in "SMUX.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#ifndef _RRspPDU_H_
-#define _RRspPDU_H_
-
-
-#include <asn_application.h>
-
-/* Including external dependencies */
-#include <INTEGER.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Dependencies */
-typedef enum RRspPDU {
- RRspPDU_failure = -1
-} e_RRspPDU;
-
-/* RRspPDU */
-typedef INTEGER_t RRspPDU_t;
-
-/* Implementation */
-extern asn_TYPE_descriptor_t asn_DEF_RRspPDU;
-asn_struct_free_f RRspPDU_free;
-asn_struct_print_f RRspPDU_print;
-asn_constr_check_f RRspPDU_constraint;
-ber_type_decoder_f RRspPDU_decode_ber;
-der_type_encoder_f RRspPDU_encode_der;
-xer_type_decoder_f RRspPDU_decode_xer;
-xer_type_encoder_f RRspPDU_encode_xer;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _RRspPDU_H_ */
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "SMUX"
- * found in "SMUX.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#include <asn_internal.h>
-
-#include "SMUX-PDUs.h"
-
-static asn_TYPE_member_t asn_MBR_SMUX_PDUs_1[] = {
- { ATF_NOFLAGS, 0, offsetof(struct SMUX_PDUs, choice.open),
- -1 /* Ambiguous tag (CHOICE?) */,
- 0,
- &asn_DEF_OpenPDU,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "open"
- },
- { ATF_NOFLAGS, 0, offsetof(struct SMUX_PDUs, choice.close),
- (ASN_TAG_CLASS_APPLICATION | (1 << 2)),
- 0,
- &asn_DEF_ClosePDU,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "close"
- },
- { ATF_NOFLAGS, 0, offsetof(struct SMUX_PDUs, choice.registerRequest),
- (ASN_TAG_CLASS_APPLICATION | (2 << 2)),
- 0,
- &asn_DEF_RReqPDU,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "registerRequest"
- },
- { ATF_NOFLAGS, 0, offsetof(struct SMUX_PDUs, choice.registerResponse),
- (ASN_TAG_CLASS_APPLICATION | (3 << 2)),
- 0,
- &asn_DEF_RRspPDU,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "registerResponse"
- },
- { ATF_NOFLAGS, 0, offsetof(struct SMUX_PDUs, choice.pdus),
- -1 /* Ambiguous tag (CHOICE?) */,
- 0,
- &asn_DEF_PDUs,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "pdus"
- },
- { ATF_NOFLAGS, 0, offsetof(struct SMUX_PDUs, choice.commitOrRollback),
- (ASN_TAG_CLASS_APPLICATION | (4 << 2)),
- 0,
- &asn_DEF_SOutPDU,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "commitOrRollback"
- },
-};
-static asn_TYPE_tag2member_t asn_MAP_SMUX_PDUs_tag2el_1[] = {
- { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 0, 0, 0 }, /* simple at 52 */
- { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 1, 0, 0 }, /* close at 27 */
- { (ASN_TAG_CLASS_APPLICATION | (2 << 2)), 2, 0, 0 }, /* registerRequest at 30 */
- { (ASN_TAG_CLASS_APPLICATION | (3 << 2)), 3, 0, 0 }, /* registerResponse at 33 */
- { (ASN_TAG_CLASS_APPLICATION | (4 << 2)), 5, 0, 0 }, /* commitOrRollback at 41 */
- { (ASN_TAG_CLASS_CONTEXT | (0 << 2)), 4, 0, 0 }, /* get-request at 34 */
- { (ASN_TAG_CLASS_CONTEXT | (1 << 2)), 4, 0, 0 }, /* get-next-request at 37 */
- { (ASN_TAG_CLASS_CONTEXT | (2 << 2)), 4, 0, 0 }, /* get-response at 40 */
- { (ASN_TAG_CLASS_CONTEXT | (3 << 2)), 4, 0, 0 }, /* set-request at 43 */
- { (ASN_TAG_CLASS_CONTEXT | (4 << 2)), 4, 0, 0 } /* trap at 47 */
-};
-static asn_CHOICE_specifics_t asn_SPC_SMUX_PDUs_specs_1 = {
- sizeof(struct SMUX_PDUs),
- offsetof(struct SMUX_PDUs, _asn_ctx),
- offsetof(struct SMUX_PDUs, present),
- sizeof(((struct SMUX_PDUs *)0)->present),
- asn_MAP_SMUX_PDUs_tag2el_1,
- 10, /* Count of tags in the map */
- 0,
- -1 /* Extensions start */
-};
-asn_TYPE_descriptor_t asn_DEF_SMUX_PDUs = {
- "SMUX-PDUs",
- "SMUX-PDUs",
- CHOICE_free,
- CHOICE_print,
- CHOICE_constraint,
- CHOICE_decode_ber,
- CHOICE_encode_der,
- CHOICE_decode_xer,
- CHOICE_encode_xer,
- 0, 0, /* No PER support, use "-gen-PER" to enable */
- CHOICE_outmost_tag,
- 0, /* No effective tags (pointer) */
- 0, /* No effective tags (count) */
- 0, /* No tags (pointer) */
- 0, /* No tags (count) */
- 0, /* No PER visible constraints */
- asn_MBR_SMUX_PDUs_1,
- 6, /* Elements count */
- &asn_SPC_SMUX_PDUs_specs_1 /* Additional specs */
-};
-
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "SMUX"
- * found in "SMUX.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#ifndef _SMUX_PDUs_H_
-#define _SMUX_PDUs_H_
-
-
-#include <asn_application.h>
-
-/* Including external dependencies */
-#include "OpenPDU.h"
-#include "ClosePDU.h"
-#include "RReqPDU.h"
-#include "RRspPDU.h"
-#include "PDUs.h"
-#include "SOutPDU.h"
-#include <constr_CHOICE.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Dependencies */
-typedef enum SMUX_PDUs_PR {
- SMUX_PDUs_PR_NOTHING, /* No components present */
- SMUX_PDUs_PR_open,
- SMUX_PDUs_PR_close,
- SMUX_PDUs_PR_registerRequest,
- SMUX_PDUs_PR_registerResponse,
- SMUX_PDUs_PR_pdus,
- SMUX_PDUs_PR_commitOrRollback
-} SMUX_PDUs_PR;
-
-/* SMUX-PDUs */
-typedef struct SMUX_PDUs {
- SMUX_PDUs_PR present;
- union SMUX_PDUs_u {
- OpenPDU_t open;
- ClosePDU_t close;
- RReqPDU_t registerRequest;
- RRspPDU_t registerResponse;
- PDUs_t pdus;
- SOutPDU_t commitOrRollback;
- } choice;
-
- /* Context for parsing across buffer boundaries */
- asn_struct_ctx_t _asn_ctx;
-} SMUX_PDUs_t;
-
-/* Implementation */
-extern asn_TYPE_descriptor_t asn_DEF_SMUX_PDUs;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SMUX_PDUs_H_ */
+++ /dev/null
-
--- WinAgents MIB Extraction Wizard\r
--- Extracted from rfc1227.txt 16.03.2005 20:20:14\r
-\r
-SMUX DEFINITIONS ::= BEGIN\r
-\r
-IMPORTS\r
- ObjectName\r
- FROM RFC1155-SMI\r
- DisplayString\r
- FROM RFC1213-MIB\r
-\r
- PDUs\r
- FROM RFC1157-SNMP;\r
-\r
-\r
--- tags for SMUX-specific PDUs are application-wide to\r
--- avoid conflict with tags for current (and future)\r
--- SNMP-generic PDUs\r
-\r
-SMUX-PDUs ::=\r
- CHOICE {\r
- open -- SMUX peer uses\r
- OpenPDU, -- immediately after TCP open\r
-\r
- close -- either uses immediately before TCP close\r
- ClosePDU,\r
-\r
- registerRequest -- SMUX peer uses\r
- RReqPDU,\r
-\r
- registerResponse -- SNMP agent uses\r
- RRspPDU,\r
-\r
- PDUs, -- note that roles are reversed:\r
- -- SNMP agent does get/get-next/set\r
- -- SMUX peer does get-response/trap\r
-\r
- commitOrRollback -- SNMP agent uses\r
- SOutPDU\r
- }\r
-\r
-\r
--- open PDU\r
--- currently only simple authentication\r
-\r
-OpenPDU ::=\r
- CHOICE {\r
- simple\r
-\r
- SimpleOpen\r
- }\r
-\r
-SimpleOpen ::=\r
- [APPLICATION 0] IMPLICIT\r
- SEQUENCE {\r
- version -- of SMUX protocol\r
- INTEGER {\r
- version-1(0)\r
- },\r
-\r
- identity -- of SMUX peer, authoritative\r
- OBJECT IDENTIFIER,\r
-\r
- description -- of SMUX peer, implementation-specific\r
- DisplayString,\r
-\r
- password -- zero length indicates no authentication\r
- OCTET STRING\r
- }\r
-\r
-\r
--- close PDU\r
-\r
-ClosePDU ::=\r
- [APPLICATION 1] IMPLICIT\r
- INTEGER {\r
- goingDown(0),\r
- unsupportedVersion(1),\r
- packetFormat(2),\r
- protocolError(3),\r
- internalError(4),\r
- authenticationFailure(5)\r
- }\r
-\r
-\r
--- insert PDU\r
-\r
-RReqPDU ::=\r
- [APPLICATION 2] IMPLICIT\r
- SEQUENCE {\r
- subtree\r
- ObjectName,\r
-\r
- priority -- the lower the better, "-1" means default\r
- INTEGER (-1..2147483647),\r
-\r
- operation\r
-\r
- INTEGER {\r
- delete(0), -- remove registration\r
- readOnly(1), -- add registration, objects are RO\r
- readWrite(2) -- .., objects are RW\r
- }\r
- }\r
-\r
-RRspPDU ::=\r
- [APPLICATION 3] IMPLICIT\r
- INTEGER {\r
- failure(-1)\r
-\r
- -- on success the non-negative priority is returned\r
- }\r
-\r
-SOutPDU ::=\r
- [APPLICATION 4] IMPLICIT\r
- INTEGER {\r
- commit(0),\r
- rollback(1)\r
- }\r
-\r
-END
\ No newline at end of file
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "SMUX"
- * found in "SMUX.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#include <asn_internal.h>
-
-#include "SOutPDU.h"
-
-int
-SOutPDU_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
- asn_app_constraint_failed_f *ctfailcb, void *app_key) {
- /* Replace with underlying type checker */
- td->check_constraints = asn_DEF_INTEGER.check_constraints;
- return td->check_constraints(td, sptr, ctfailcb, app_key);
-}
-
-/*
- * This type is implemented using INTEGER,
- * so here we adjust the DEF accordingly.
- */
-static void
-SOutPDU_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
- td->free_struct = asn_DEF_INTEGER.free_struct;
- td->print_struct = asn_DEF_INTEGER.print_struct;
- td->ber_decoder = asn_DEF_INTEGER.ber_decoder;
- td->der_encoder = asn_DEF_INTEGER.der_encoder;
- td->xer_decoder = asn_DEF_INTEGER.xer_decoder;
- td->xer_encoder = asn_DEF_INTEGER.xer_encoder;
- td->uper_decoder = asn_DEF_INTEGER.uper_decoder;
- td->uper_encoder = asn_DEF_INTEGER.uper_encoder;
- if(!td->per_constraints)
- td->per_constraints = asn_DEF_INTEGER.per_constraints;
- td->elements = asn_DEF_INTEGER.elements;
- td->elements_count = asn_DEF_INTEGER.elements_count;
- td->specifics = asn_DEF_INTEGER.specifics;
-}
-
-void
-SOutPDU_free(asn_TYPE_descriptor_t *td,
- void *struct_ptr, int contents_only) {
- SOutPDU_1_inherit_TYPE_descriptor(td);
- td->free_struct(td, struct_ptr, contents_only);
-}
-
-int
-SOutPDU_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
- int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
- SOutPDU_1_inherit_TYPE_descriptor(td);
- return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
-}
-
-asn_dec_rval_t
-SOutPDU_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
- void **structure, const void *bufptr, size_t size, int tag_mode) {
- SOutPDU_1_inherit_TYPE_descriptor(td);
- return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode);
-}
-
-asn_enc_rval_t
-SOutPDU_encode_der(asn_TYPE_descriptor_t *td,
- void *structure, int tag_mode, ber_tlv_tag_t tag,
- asn_app_consume_bytes_f *cb, void *app_key) {
- SOutPDU_1_inherit_TYPE_descriptor(td);
- return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
-}
-
-asn_dec_rval_t
-SOutPDU_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
- void **structure, const char *opt_mname, const void *bufptr, size_t size) {
- SOutPDU_1_inherit_TYPE_descriptor(td);
- return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size);
-}
-
-asn_enc_rval_t
-SOutPDU_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
- int ilevel, enum xer_encoder_flags_e flags,
- asn_app_consume_bytes_f *cb, void *app_key) {
- SOutPDU_1_inherit_TYPE_descriptor(td);
- return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
-}
-
-static ber_tlv_tag_t asn_DEF_SOutPDU_tags_1[] = {
- (ASN_TAG_CLASS_APPLICATION | (4 << 2)),
- (ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
-};
-asn_TYPE_descriptor_t asn_DEF_SOutPDU = {
- "SOutPDU",
- "SOutPDU",
- SOutPDU_free,
- SOutPDU_print,
- SOutPDU_constraint,
- SOutPDU_decode_ber,
- SOutPDU_encode_der,
- SOutPDU_decode_xer,
- SOutPDU_encode_xer,
- 0, 0, /* No PER support, use "-gen-PER" to enable */
- 0, /* Use generic outmost tag fetcher */
- asn_DEF_SOutPDU_tags_1,
- sizeof(asn_DEF_SOutPDU_tags_1)
- /sizeof(asn_DEF_SOutPDU_tags_1[0]) - 1, /* 1 */
- asn_DEF_SOutPDU_tags_1, /* Same as above */
- sizeof(asn_DEF_SOutPDU_tags_1)
- /sizeof(asn_DEF_SOutPDU_tags_1[0]), /* 2 */
- 0, /* No PER visible constraints */
- 0, 0, /* Defined elsewhere */
- 0 /* No specifics */
-};
-
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "SMUX"
- * found in "SMUX.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#ifndef _SOutPDU_H_
-#define _SOutPDU_H_
-
-
-#include <asn_application.h>
-
-/* Including external dependencies */
-#include <INTEGER.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Dependencies */
-typedef enum SOutPDU {
- SOutPDU_commit = 0,
- SOutPDU_rollback = 1
-} e_SOutPDU;
-
-/* SOutPDU */
-typedef INTEGER_t SOutPDU_t;
-
-/* Implementation */
-extern asn_TYPE_descriptor_t asn_DEF_SOutPDU;
-asn_struct_free_f SOutPDU_free;
-asn_struct_print_f SOutPDU_print;
-asn_constr_check_f SOutPDU_constraint;
-ber_type_decoder_f SOutPDU_decode_ber;
-der_type_encoder_f SOutPDU_encode_der;
-xer_type_decoder_f SOutPDU_decode_xer;
-xer_type_encoder_f SOutPDU_encode_xer;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SOutPDU_H_ */
+++ /dev/null
-STG-MIB DEFINITIONS ::=
-
-BEGIN
-
-IMPORTS
- enterprises, OBJECT-TYPE FROM RFC1155-SMI
- MODULE-IDENTITY, OBJECT-TYPE, Integer32,
- NOTIFICATION-TYPE FROM SNMPv2-SMI
-
-stgMIB MODULE-IDENTITY
- LAST-UPDATED "201101060000Z"
- ORGANIZATION "STG"
- CONTACT-INFO
- "Primary Contact: Maxim Mamontov
- email: faust@stg.dp.ua"
- DESCRIPTION
- "This MIB module defines objects for Stargazer derived data."
- REVISION "201101060000Z"
- DESCRIPTION
- "Derived from LM_SENSORS."
- ::= { enterprises 9363 }
-
-stgMIB ::= OBJECT IDENTIFIER { enterprises 9363 }
-
-stg-24 ::= OBJECT IDENTIFIER { stgMIB 1 }
-
-users ::= OBJECT IDENTIFIER { stg-24 1 }
-tariffs ::= OBJECT IDENTIFIER { stg-24 2 }
-admins ::= OBJECT IDENTIFIER { stg-24 3 }
-services ::= OBJECT IDENTIFIER { stg-24 4 }
-corporations ::= OBJECT IDENTIFIER { stg-24 5 }
-
-totalUsers OBJECT-TYPE
- SYNTAX Integer32
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Total users registered in the billing"
- DEFVAL { 0 }
- ::= { users 1 }
-
-onlineUsers OBJECT-TYPE
- SYNTAX Integer32
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "The number of currently online users"
- DEFVAL { 0 }
- ::= { users 2 }
-
-authorizedUsers OBJECT-TYPE
- SYNTAX Integer32
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "The number of currently authorized users"
- DEFVAL { 0 }
- ::= { users 3 }
-
-alwaysOnlineUsers OBJECT-TYPE
- SYNTAX Integer32
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "The number of users with 'always online' option"
- DEFVAL { 0 }
- ::= { users 4 }
-
-noCashUsers OBJECT-TYPE
- SYNTAX Integer32
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "The number of users with negative cash"
- DEFVAL { 0 }
- ::= { users 5 }
-
-tariffUsers OBJECT-TYPE
- SYNTAX SEQUENCE OF UsersByTariff
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "The number of users with negative cash"
- DEFVAL { 0 }
- ::= { users 6 }
-
-UsersByTariff ::= SEQUENCE
- {
- tariffId Integer32,
- tariffName DisplayString,
- userCount Integer32
- }
-
-disabledDetailStatsUsers OBJECT-TYPE
- SYNTAX Integer32
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "The number of users with disabled detail stats"
- DEFVAL { 0 }
- ::= { users 7 }
-
-disabledUsers OBJECT-TYPE
- SYNTAX Integer32
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "The number of disabled users"
- DEFVAL { 0 }
- ::= { users 8 }
-
-passiveUsers OBJECT-TYPE
- SYNTAX Integer32
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "The number of passive users"
- DEFVAL { 0 }
- ::= { users 9 }
-
-creditUsers OBJECT-TYPE
- SYNTAX Integer32
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "The number of users with positive credit"
- DEFVAL { 0 }
- ::= { users 10 }
-
-freeMbUsers OBJECT-TYPE
- SYNTAX Integer32
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "The number of users with positive freeMb"
- DEFVAL { 0 }
- ::= { users 11 }
-
-totalTariffs OBJECT-TYPE
- SYNTAX Integer32
- MAX-ACCESS read-only
- STATUS current
- DESCRIPTION
- "Total tariffs registered in the billing"
- DEFVAL { 0 }
- ::= { tariffs 1 }
-
-END
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1157-SNMP"
- * found in "RFC1157-SNMP.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#include <asn_internal.h>
-
-#include "SetRequest-PDU.h"
-
-int
-SetRequest_PDU_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
- asn_app_constraint_failed_f *ctfailcb, void *app_key) {
- /* Replace with underlying type checker */
- td->check_constraints = asn_DEF_PDU.check_constraints;
- return td->check_constraints(td, sptr, ctfailcb, app_key);
-}
-
-/*
- * This type is implemented using PDU,
- * so here we adjust the DEF accordingly.
- */
-static void
-SetRequest_PDU_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
- td->free_struct = asn_DEF_PDU.free_struct;
- td->print_struct = asn_DEF_PDU.print_struct;
- td->ber_decoder = asn_DEF_PDU.ber_decoder;
- td->der_encoder = asn_DEF_PDU.der_encoder;
- td->xer_decoder = asn_DEF_PDU.xer_decoder;
- td->xer_encoder = asn_DEF_PDU.xer_encoder;
- td->uper_decoder = asn_DEF_PDU.uper_decoder;
- td->uper_encoder = asn_DEF_PDU.uper_encoder;
- if(!td->per_constraints)
- td->per_constraints = asn_DEF_PDU.per_constraints;
- td->elements = asn_DEF_PDU.elements;
- td->elements_count = asn_DEF_PDU.elements_count;
- td->specifics = asn_DEF_PDU.specifics;
-}
-
-void
-SetRequest_PDU_free(asn_TYPE_descriptor_t *td,
- void *struct_ptr, int contents_only) {
- SetRequest_PDU_1_inherit_TYPE_descriptor(td);
- td->free_struct(td, struct_ptr, contents_only);
-}
-
-int
-SetRequest_PDU_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
- int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
- SetRequest_PDU_1_inherit_TYPE_descriptor(td);
- return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
-}
-
-asn_dec_rval_t
-SetRequest_PDU_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
- void **structure, const void *bufptr, size_t size, int tag_mode) {
- SetRequest_PDU_1_inherit_TYPE_descriptor(td);
- return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode);
-}
-
-asn_enc_rval_t
-SetRequest_PDU_encode_der(asn_TYPE_descriptor_t *td,
- void *structure, int tag_mode, ber_tlv_tag_t tag,
- asn_app_consume_bytes_f *cb, void *app_key) {
- SetRequest_PDU_1_inherit_TYPE_descriptor(td);
- return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
-}
-
-asn_dec_rval_t
-SetRequest_PDU_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
- void **structure, const char *opt_mname, const void *bufptr, size_t size) {
- SetRequest_PDU_1_inherit_TYPE_descriptor(td);
- return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size);
-}
-
-asn_enc_rval_t
-SetRequest_PDU_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
- int ilevel, enum xer_encoder_flags_e flags,
- asn_app_consume_bytes_f *cb, void *app_key) {
- SetRequest_PDU_1_inherit_TYPE_descriptor(td);
- return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
-}
-
-static ber_tlv_tag_t asn_DEF_SetRequest_PDU_tags_1[] = {
- (ASN_TAG_CLASS_CONTEXT | (3 << 2)),
- (ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
-};
-asn_TYPE_descriptor_t asn_DEF_SetRequest_PDU = {
- "SetRequest-PDU",
- "SetRequest-PDU",
- SetRequest_PDU_free,
- SetRequest_PDU_print,
- SetRequest_PDU_constraint,
- SetRequest_PDU_decode_ber,
- SetRequest_PDU_encode_der,
- SetRequest_PDU_decode_xer,
- SetRequest_PDU_encode_xer,
- 0, 0, /* No PER support, use "-gen-PER" to enable */
- 0, /* Use generic outmost tag fetcher */
- asn_DEF_SetRequest_PDU_tags_1,
- sizeof(asn_DEF_SetRequest_PDU_tags_1)
- /sizeof(asn_DEF_SetRequest_PDU_tags_1[0]) - 1, /* 1 */
- asn_DEF_SetRequest_PDU_tags_1, /* Same as above */
- sizeof(asn_DEF_SetRequest_PDU_tags_1)
- /sizeof(asn_DEF_SetRequest_PDU_tags_1[0]), /* 2 */
- 0, /* No PER visible constraints */
- 0, 0, /* Defined elsewhere */
- 0 /* No specifics */
-};
-
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1157-SNMP"
- * found in "RFC1157-SNMP.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#ifndef _SetRequest_PDU_H_
-#define _SetRequest_PDU_H_
-
-
-#include <asn_application.h>
-
-/* Including external dependencies */
-#include "PDU.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* SetRequest-PDU */
-typedef PDU_t SetRequest_PDU_t;
-
-/* Implementation */
-extern asn_TYPE_descriptor_t asn_DEF_SetRequest_PDU;
-asn_struct_free_f SetRequest_PDU_free;
-asn_struct_print_f SetRequest_PDU_print;
-asn_constr_check_f SetRequest_PDU_constraint;
-ber_type_decoder_f SetRequest_PDU_decode_ber;
-der_type_encoder_f SetRequest_PDU_encode_der;
-xer_type_decoder_f SetRequest_PDU_decode_xer;
-xer_type_encoder_f SetRequest_PDU_encode_xer;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SetRequest_PDU_H_ */
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "SMUX"
- * found in "SMUX.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#include <asn_internal.h>
-
-#include "SimpleOpen.h"
-
-static asn_TYPE_member_t asn_MBR_SimpleOpen_1[] = {
- { ATF_NOFLAGS, 0, offsetof(struct SimpleOpen, version),
- (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
- 0,
- &asn_DEF_INTEGER,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "version"
- },
- { ATF_NOFLAGS, 0, offsetof(struct SimpleOpen, identity),
- (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)),
- 0,
- &asn_DEF_OBJECT_IDENTIFIER,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "identity"
- },
- { ATF_NOFLAGS, 0, offsetof(struct SimpleOpen, description),
- (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)),
- 0,
- &asn_DEF_DisplayString,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "description"
- },
- { ATF_NOFLAGS, 0, offsetof(struct SimpleOpen, password),
- (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)),
- 0,
- &asn_DEF_OCTET_STRING,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "password"
- },
-};
-static ber_tlv_tag_t asn_DEF_SimpleOpen_tags_1[] = {
- (ASN_TAG_CLASS_APPLICATION | (0 << 2)),
- (ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
-};
-static asn_TYPE_tag2member_t asn_MAP_SimpleOpen_tag2el_1[] = {
- { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 0 }, /* version at 59 */
- { (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 2, 0, 1 }, /* description at 66 */
- { (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 3, -1, 0 }, /* password at 69 */
- { (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)), 1, 0, 0 } /* identity at 63 */
-};
-static asn_SEQUENCE_specifics_t asn_SPC_SimpleOpen_specs_1 = {
- sizeof(struct SimpleOpen),
- offsetof(struct SimpleOpen, _asn_ctx),
- asn_MAP_SimpleOpen_tag2el_1,
- 4, /* Count of tags in the map */
- 0, 0, 0, /* Optional elements (not needed) */
- -1, /* Start extensions */
- -1 /* Stop extensions */
-};
-asn_TYPE_descriptor_t asn_DEF_SimpleOpen = {
- "SimpleOpen",
- "SimpleOpen",
- SEQUENCE_free,
- SEQUENCE_print,
- SEQUENCE_constraint,
- SEQUENCE_decode_ber,
- SEQUENCE_encode_der,
- SEQUENCE_decode_xer,
- SEQUENCE_encode_xer,
- 0, 0, /* No PER support, use "-gen-PER" to enable */
- 0, /* Use generic outmost tag fetcher */
- asn_DEF_SimpleOpen_tags_1,
- sizeof(asn_DEF_SimpleOpen_tags_1)
- /sizeof(asn_DEF_SimpleOpen_tags_1[0]) - 1, /* 1 */
- asn_DEF_SimpleOpen_tags_1, /* Same as above */
- sizeof(asn_DEF_SimpleOpen_tags_1)
- /sizeof(asn_DEF_SimpleOpen_tags_1[0]), /* 2 */
- 0, /* No PER visible constraints */
- asn_MBR_SimpleOpen_1,
- 4, /* Elements count */
- &asn_SPC_SimpleOpen_specs_1 /* Additional specs */
-};
-
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "SMUX"
- * found in "SMUX.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#ifndef _SimpleOpen_H_
-#define _SimpleOpen_H_
-
-
-#include <asn_application.h>
-
-/* Including external dependencies */
-#include <INTEGER.h>
-#include <OBJECT_IDENTIFIER.h>
-#include "DisplayString.h"
-#include <OCTET_STRING.h>
-#include <constr_SEQUENCE.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Dependencies */
-typedef enum SimpleOpen__version {
- SimpleOpen__version_version_1 = 0
-} e_SimpleOpen__version;
-
-/* SimpleOpen */
-typedef struct SimpleOpen {
- INTEGER_t version;
- OBJECT_IDENTIFIER_t identity;
- DisplayString_t description;
- OCTET_STRING_t password;
-
- /* Context for parsing across buffer boundaries */
- asn_struct_ctx_t _asn_ctx;
-} SimpleOpen_t;
-
-/* Implementation */
-extern asn_TYPE_descriptor_t asn_DEF_SimpleOpen;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SimpleOpen_H_ */
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1155-SMI"
- * found in "RFC1155-SMI.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#include <asn_internal.h>
-
-#include "SimpleSyntax.h"
-
-static asn_TYPE_member_t asn_MBR_SimpleSyntax_1[] = {
- { ATF_NOFLAGS, 0, offsetof(struct SimpleSyntax, choice.number),
- (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
- 0,
- &asn_DEF_INTEGER,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "number"
- },
- { ATF_NOFLAGS, 0, offsetof(struct SimpleSyntax, choice.string),
- (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)),
- 0,
- &asn_DEF_OCTET_STRING,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "string"
- },
- { ATF_NOFLAGS, 0, offsetof(struct SimpleSyntax, choice.object),
- (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)),
- 0,
- &asn_DEF_OBJECT_IDENTIFIER,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "object"
- },
- { ATF_NOFLAGS, 0, offsetof(struct SimpleSyntax, choice.empty),
- (ASN_TAG_CLASS_UNIVERSAL | (5 << 2)),
- 0,
- &asn_DEF_NULL,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "empty"
- },
-};
-static asn_TYPE_tag2member_t asn_MAP_SimpleSyntax_tag2el_1[] = {
- { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 0 }, /* number at 73 */
- { (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 1, 0, 0 }, /* string at 76 */
- { (ASN_TAG_CLASS_UNIVERSAL | (5 << 2)), 3, 0, 0 }, /* empty at 82 */
- { (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)), 2, 0, 0 } /* object at 79 */
-};
-static asn_CHOICE_specifics_t asn_SPC_SimpleSyntax_specs_1 = {
- sizeof(struct SimpleSyntax),
- offsetof(struct SimpleSyntax, _asn_ctx),
- offsetof(struct SimpleSyntax, present),
- sizeof(((struct SimpleSyntax *)0)->present),
- asn_MAP_SimpleSyntax_tag2el_1,
- 4, /* Count of tags in the map */
- 0,
- -1 /* Extensions start */
-};
-asn_TYPE_descriptor_t asn_DEF_SimpleSyntax = {
- "SimpleSyntax",
- "SimpleSyntax",
- CHOICE_free,
- CHOICE_print,
- CHOICE_constraint,
- CHOICE_decode_ber,
- CHOICE_encode_der,
- CHOICE_decode_xer,
- CHOICE_encode_xer,
- 0, 0, /* No PER support, use "-gen-PER" to enable */
- CHOICE_outmost_tag,
- 0, /* No effective tags (pointer) */
- 0, /* No effective tags (count) */
- 0, /* No tags (pointer) */
- 0, /* No tags (count) */
- 0, /* No PER visible constraints */
- asn_MBR_SimpleSyntax_1,
- 4, /* Elements count */
- &asn_SPC_SimpleSyntax_specs_1 /* Additional specs */
-};
-
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1155-SMI"
- * found in "RFC1155-SMI.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#ifndef _SimpleSyntax_H_
-#define _SimpleSyntax_H_
-
-
-#include <asn_application.h>
-
-/* Including external dependencies */
-#include <INTEGER.h>
-#include <OCTET_STRING.h>
-#include <OBJECT_IDENTIFIER.h>
-#include <NULL.h>
-#include <constr_CHOICE.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Dependencies */
-typedef enum SimpleSyntax_PR {
- SimpleSyntax_PR_NOTHING, /* No components present */
- SimpleSyntax_PR_number,
- SimpleSyntax_PR_string,
- SimpleSyntax_PR_object,
- SimpleSyntax_PR_empty
-} SimpleSyntax_PR;
-
-/* SimpleSyntax */
-typedef struct SimpleSyntax {
- SimpleSyntax_PR present;
- union SimpleSyntax_u {
- INTEGER_t number;
- OCTET_STRING_t string;
- OBJECT_IDENTIFIER_t object;
- NULL_t empty;
- } choice;
-
- /* Context for parsing across buffer boundaries */
- asn_struct_ctx_t _asn_ctx;
-} SimpleSyntax_t;
-
-/* Implementation */
-extern asn_TYPE_descriptor_t asn_DEF_SimpleSyntax;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SimpleSyntax_H_ */
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1213-MIB"
- * found in "RFC1213-MIB.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#include <asn_internal.h>
-
-#include "TcpConnEntry.h"
-
-static int
-memb_tcpConnLocalPort_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr,
- asn_app_constraint_failed_f *ctfailcb, void *app_key) {
- long value;
-
- if(!sptr) {
- _ASN_CTFAIL(app_key, td, sptr,
- "%s: value not given (%s:%d)",
- td->name, __FILE__, __LINE__);
- return -1;
- }
-
- value = *(const long *)sptr;
-
- if((value >= 0 && value <= 65535)) {
- /* Constraint check succeeded */
- return 0;
- } else {
- _ASN_CTFAIL(app_key, td, sptr,
- "%s: constraint failed (%s:%d)",
- td->name, __FILE__, __LINE__);
- return -1;
- }
-}
-
-static int
-memb_tcpConnRemPort_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr,
- asn_app_constraint_failed_f *ctfailcb, void *app_key) {
- long value;
-
- if(!sptr) {
- _ASN_CTFAIL(app_key, td, sptr,
- "%s: value not given (%s:%d)",
- td->name, __FILE__, __LINE__);
- return -1;
- }
-
- value = *(const long *)sptr;
-
- if((value >= 0 && value <= 65535)) {
- /* Constraint check succeeded */
- return 0;
- } else {
- _ASN_CTFAIL(app_key, td, sptr,
- "%s: constraint failed (%s:%d)",
- td->name, __FILE__, __LINE__);
- return -1;
- }
-}
-
-static asn_TYPE_member_t asn_MBR_TcpConnEntry_1[] = {
- { ATF_NOFLAGS, 0, offsetof(struct TcpConnEntry, tcpConnState),
- (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
- 0,
- &asn_DEF_INTEGER,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "tcpConnState"
- },
- { ATF_NOFLAGS, 0, offsetof(struct TcpConnEntry, tcpConnLocalAddress),
- (ASN_TAG_CLASS_APPLICATION | (0 << 2)),
- 0,
- &asn_DEF_IpAddress,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "tcpConnLocalAddress"
- },
- { ATF_NOFLAGS, 0, offsetof(struct TcpConnEntry, tcpConnLocalPort),
- (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
- 0,
- &asn_DEF_NativeInteger,
- memb_tcpConnLocalPort_constraint_1,
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "tcpConnLocalPort"
- },
- { ATF_NOFLAGS, 0, offsetof(struct TcpConnEntry, tcpConnRemAddress),
- (ASN_TAG_CLASS_APPLICATION | (0 << 2)),
- 0,
- &asn_DEF_IpAddress,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "tcpConnRemAddress"
- },
- { ATF_NOFLAGS, 0, offsetof(struct TcpConnEntry, tcpConnRemPort),
- (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
- 0,
- &asn_DEF_NativeInteger,
- memb_tcpConnRemPort_constraint_1,
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "tcpConnRemPort"
- },
-};
-static ber_tlv_tag_t asn_DEF_TcpConnEntry_tags_1[] = {
- (ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
-};
-static asn_TYPE_tag2member_t asn_MAP_TcpConnEntry_tag2el_1[] = {
- { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 2 }, /* tcpConnState at 236 */
- { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 2, -1, 1 }, /* tcpConnLocalPort at 240 */
- { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 4, -2, 0 }, /* tcpConnRemPort at 244 */
- { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 1, 0, 1 }, /* tcpConnLocalAddress at 238 */
- { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 3, -1, 0 } /* tcpConnRemAddress at 242 */
-};
-static asn_SEQUENCE_specifics_t asn_SPC_TcpConnEntry_specs_1 = {
- sizeof(struct TcpConnEntry),
- offsetof(struct TcpConnEntry, _asn_ctx),
- asn_MAP_TcpConnEntry_tag2el_1,
- 5, /* Count of tags in the map */
- 0, 0, 0, /* Optional elements (not needed) */
- -1, /* Start extensions */
- -1 /* Stop extensions */
-};
-asn_TYPE_descriptor_t asn_DEF_TcpConnEntry = {
- "TcpConnEntry",
- "TcpConnEntry",
- SEQUENCE_free,
- SEQUENCE_print,
- SEQUENCE_constraint,
- SEQUENCE_decode_ber,
- SEQUENCE_encode_der,
- SEQUENCE_decode_xer,
- SEQUENCE_encode_xer,
- 0, 0, /* No PER support, use "-gen-PER" to enable */
- 0, /* Use generic outmost tag fetcher */
- asn_DEF_TcpConnEntry_tags_1,
- sizeof(asn_DEF_TcpConnEntry_tags_1)
- /sizeof(asn_DEF_TcpConnEntry_tags_1[0]), /* 1 */
- asn_DEF_TcpConnEntry_tags_1, /* Same as above */
- sizeof(asn_DEF_TcpConnEntry_tags_1)
- /sizeof(asn_DEF_TcpConnEntry_tags_1[0]), /* 1 */
- 0, /* No PER visible constraints */
- asn_MBR_TcpConnEntry_1,
- 5, /* Elements count */
- &asn_SPC_TcpConnEntry_specs_1 /* Additional specs */
-};
-
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1213-MIB"
- * found in "RFC1213-MIB.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#ifndef _TcpConnEntry_H_
-#define _TcpConnEntry_H_
-
-
-#include <asn_application.h>
-
-/* Including external dependencies */
-#include <INTEGER.h>
-#include "IpAddress.h"
-#include <NativeInteger.h>
-#include <constr_SEQUENCE.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* TcpConnEntry */
-typedef struct TcpConnEntry {
- INTEGER_t tcpConnState;
- IpAddress_t tcpConnLocalAddress;
- long tcpConnLocalPort;
- IpAddress_t tcpConnRemAddress;
- long tcpConnRemPort;
-
- /* Context for parsing across buffer boundaries */
- asn_struct_ctx_t _asn_ctx;
-} TcpConnEntry_t;
-
-/* Implementation */
-extern asn_TYPE_descriptor_t asn_DEF_TcpConnEntry;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _TcpConnEntry_H_ */
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1155-SMI"
- * found in "RFC1155-SMI.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#include <asn_internal.h>
-
-#include "TimeTicks.h"
-
-int
-TimeTicks_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
- asn_app_constraint_failed_f *ctfailcb, void *app_key) {
- const INTEGER_t *st = (const INTEGER_t *)sptr;
- long value;
-
- if(!sptr) {
- _ASN_CTFAIL(app_key, td, sptr,
- "%s: value not given (%s:%d)",
- td->name, __FILE__, __LINE__);
- return -1;
- }
-
- if(asn_INTEGER2long(st, &value)) {
- _ASN_CTFAIL(app_key, td, sptr,
- "%s: value too large (%s:%d)",
- td->name, __FILE__, __LINE__);
- return -1;
- }
-
- if((value >= 0 && value <= 4294967295)) {
- /* Constraint check succeeded */
- return 0;
- } else {
- _ASN_CTFAIL(app_key, td, sptr,
- "%s: constraint failed (%s:%d)",
- td->name, __FILE__, __LINE__);
- return -1;
- }
-}
-
-/*
- * This type is implemented using INTEGER,
- * so here we adjust the DEF accordingly.
- */
-static void
-TimeTicks_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
- td->free_struct = asn_DEF_INTEGER.free_struct;
- td->print_struct = asn_DEF_INTEGER.print_struct;
- td->ber_decoder = asn_DEF_INTEGER.ber_decoder;
- td->der_encoder = asn_DEF_INTEGER.der_encoder;
- td->xer_decoder = asn_DEF_INTEGER.xer_decoder;
- td->xer_encoder = asn_DEF_INTEGER.xer_encoder;
- td->uper_decoder = asn_DEF_INTEGER.uper_decoder;
- td->uper_encoder = asn_DEF_INTEGER.uper_encoder;
- if(!td->per_constraints)
- td->per_constraints = asn_DEF_INTEGER.per_constraints;
- td->elements = asn_DEF_INTEGER.elements;
- td->elements_count = asn_DEF_INTEGER.elements_count;
- td->specifics = asn_DEF_INTEGER.specifics;
-}
-
-void
-TimeTicks_free(asn_TYPE_descriptor_t *td,
- void *struct_ptr, int contents_only) {
- TimeTicks_1_inherit_TYPE_descriptor(td);
- td->free_struct(td, struct_ptr, contents_only);
-}
-
-int
-TimeTicks_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
- int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
- TimeTicks_1_inherit_TYPE_descriptor(td);
- return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
-}
-
-asn_dec_rval_t
-TimeTicks_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
- void **structure, const void *bufptr, size_t size, int tag_mode) {
- TimeTicks_1_inherit_TYPE_descriptor(td);
- return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode);
-}
-
-asn_enc_rval_t
-TimeTicks_encode_der(asn_TYPE_descriptor_t *td,
- void *structure, int tag_mode, ber_tlv_tag_t tag,
- asn_app_consume_bytes_f *cb, void *app_key) {
- TimeTicks_1_inherit_TYPE_descriptor(td);
- return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
-}
-
-asn_dec_rval_t
-TimeTicks_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
- void **structure, const char *opt_mname, const void *bufptr, size_t size) {
- TimeTicks_1_inherit_TYPE_descriptor(td);
- return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size);
-}
-
-asn_enc_rval_t
-TimeTicks_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
- int ilevel, enum xer_encoder_flags_e flags,
- asn_app_consume_bytes_f *cb, void *app_key) {
- TimeTicks_1_inherit_TYPE_descriptor(td);
- return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
-}
-
-static ber_tlv_tag_t asn_DEF_TimeTicks_tags_1[] = {
- (ASN_TAG_CLASS_APPLICATION | (3 << 2)),
- (ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
-};
-asn_TYPE_descriptor_t asn_DEF_TimeTicks = {
- "TimeTicks",
- "TimeTicks",
- TimeTicks_free,
- TimeTicks_print,
- TimeTicks_constraint,
- TimeTicks_decode_ber,
- TimeTicks_encode_der,
- TimeTicks_decode_xer,
- TimeTicks_encode_xer,
- 0, 0, /* No PER support, use "-gen-PER" to enable */
- 0, /* Use generic outmost tag fetcher */
- asn_DEF_TimeTicks_tags_1,
- sizeof(asn_DEF_TimeTicks_tags_1)
- /sizeof(asn_DEF_TimeTicks_tags_1[0]) - 1, /* 1 */
- asn_DEF_TimeTicks_tags_1, /* Same as above */
- sizeof(asn_DEF_TimeTicks_tags_1)
- /sizeof(asn_DEF_TimeTicks_tags_1[0]), /* 2 */
- 0, /* No PER visible constraints */
- 0, 0, /* No members */
- 0 /* No specifics */
-};
-
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1155-SMI"
- * found in "RFC1155-SMI.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#ifndef _TimeTicks_H_
-#define _TimeTicks_H_
-
-
-#include <asn_application.h>
-
-/* Including external dependencies */
-#include <INTEGER.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* TimeTicks */
-typedef INTEGER_t TimeTicks_t;
-
-/* Implementation */
-extern asn_TYPE_descriptor_t asn_DEF_TimeTicks;
-asn_struct_free_f TimeTicks_free;
-asn_struct_print_f TimeTicks_print;
-asn_constr_check_f TimeTicks_constraint;
-ber_type_decoder_f TimeTicks_decode_ber;
-der_type_encoder_f TimeTicks_encode_der;
-xer_type_decoder_f TimeTicks_decode_xer;
-xer_type_encoder_f TimeTicks_encode_xer;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _TimeTicks_H_ */
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1157-SNMP"
- * found in "RFC1157-SNMP.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#include <asn_internal.h>
-
-#include "Trap-PDU.h"
-
-static asn_TYPE_member_t asn_MBR_Trap_PDU_1[] = {
- { ATF_NOFLAGS, 0, offsetof(struct Trap_PDU, enterprise),
- (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)),
- 0,
- &asn_DEF_OBJECT_IDENTIFIER,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "enterprise"
- },
- { ATF_NOFLAGS, 0, offsetof(struct Trap_PDU, agent_addr),
- -1 /* Ambiguous tag (CHOICE?) */,
- 0,
- &asn_DEF_NetworkAddress,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "agent-addr"
- },
- { ATF_NOFLAGS, 0, offsetof(struct Trap_PDU, generic_trap),
- (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
- 0,
- &asn_DEF_INTEGER,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "generic-trap"
- },
- { ATF_NOFLAGS, 0, offsetof(struct Trap_PDU, specific_trap),
- (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
- 0,
- &asn_DEF_INTEGER,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "specific-trap"
- },
- { ATF_NOFLAGS, 0, offsetof(struct Trap_PDU, time_stamp),
- (ASN_TAG_CLASS_APPLICATION | (3 << 2)),
- 0,
- &asn_DEF_TimeTicks,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "time-stamp"
- },
- { ATF_NOFLAGS, 0, offsetof(struct Trap_PDU, variable_bindings),
- (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)),
- 0,
- &asn_DEF_VarBindList,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "variable-bindings"
- },
-};
-static ber_tlv_tag_t asn_DEF_Trap_PDU_tags_1[] = {
- (ASN_TAG_CLASS_CONTEXT | (4 << 2)),
- (ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
-};
-static asn_TYPE_tag2member_t asn_MAP_Trap_PDU_tag2el_1[] = {
- { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 2, 0, 1 }, /* generic-trap at 106 */
- { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 3, -1, 0 }, /* specific-trap at 116 */
- { (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)), 0, 0, 0 }, /* enterprise at 99 */
- { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)), 5, 0, 0 }, /* variable-bindings at 125 */
- { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 1, 0, 0 }, /* internet at 113 */
- { (ASN_TAG_CLASS_APPLICATION | (3 << 2)), 4, 0, 0 } /* time-stamp at 120 */
-};
-static asn_SEQUENCE_specifics_t asn_SPC_Trap_PDU_specs_1 = {
- sizeof(struct Trap_PDU),
- offsetof(struct Trap_PDU, _asn_ctx),
- asn_MAP_Trap_PDU_tag2el_1,
- 6, /* Count of tags in the map */
- 0, 0, 0, /* Optional elements (not needed) */
- -1, /* Start extensions */
- -1 /* Stop extensions */
-};
-asn_TYPE_descriptor_t asn_DEF_Trap_PDU = {
- "Trap-PDU",
- "Trap-PDU",
- SEQUENCE_free,
- SEQUENCE_print,
- SEQUENCE_constraint,
- SEQUENCE_decode_ber,
- SEQUENCE_encode_der,
- SEQUENCE_decode_xer,
- SEQUENCE_encode_xer,
- 0, 0, /* No PER support, use "-gen-PER" to enable */
- 0, /* Use generic outmost tag fetcher */
- asn_DEF_Trap_PDU_tags_1,
- sizeof(asn_DEF_Trap_PDU_tags_1)
- /sizeof(asn_DEF_Trap_PDU_tags_1[0]) - 1, /* 1 */
- asn_DEF_Trap_PDU_tags_1, /* Same as above */
- sizeof(asn_DEF_Trap_PDU_tags_1)
- /sizeof(asn_DEF_Trap_PDU_tags_1[0]), /* 2 */
- 0, /* No PER visible constraints */
- asn_MBR_Trap_PDU_1,
- 6, /* Elements count */
- &asn_SPC_Trap_PDU_specs_1 /* Additional specs */
-};
-
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1157-SNMP"
- * found in "RFC1157-SNMP.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#ifndef _Trap_PDU_H_
-#define _Trap_PDU_H_
-
-
-#include <asn_application.h>
-
-/* Including external dependencies */
-#include <OBJECT_IDENTIFIER.h>
-#include "NetworkAddress.h"
-#include <INTEGER.h>
-#include "TimeTicks.h"
-#include "VarBindList.h"
-#include <constr_SEQUENCE.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Dependencies */
-typedef enum Trap_PDU__generic_trap {
- Trap_PDU__generic_trap_coldStart = 0,
- Trap_PDU__generic_trap_warmStart = 1,
- Trap_PDU__generic_trap_linkDown = 2,
- Trap_PDU__generic_trap_linkUp = 3,
- Trap_PDU__generic_trap_authenticationFailure = 4,
- Trap_PDU__generic_trap_egpNeighborLoss = 5,
- Trap_PDU__generic_trap_enterpriseSpecific = 6
-} e_Trap_PDU__generic_trap;
-
-/* Trap-PDU */
-typedef struct Trap_PDU {
- OBJECT_IDENTIFIER_t enterprise;
- NetworkAddress_t agent_addr;
- INTEGER_t generic_trap;
- INTEGER_t specific_trap;
- TimeTicks_t time_stamp;
- VarBindList_t variable_bindings;
-
- /* Context for parsing across buffer boundaries */
- asn_struct_ctx_t _asn_ctx;
-} Trap_PDU_t;
-
-/* Implementation */
-extern asn_TYPE_descriptor_t asn_DEF_Trap_PDU;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _Trap_PDU_H_ */
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1213-MIB"
- * found in "RFC1213-MIB.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#include <asn_internal.h>
-
-#include "UdpEntry.h"
-
-static int
-memb_udpLocalPort_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr,
- asn_app_constraint_failed_f *ctfailcb, void *app_key) {
- long value;
-
- if(!sptr) {
- _ASN_CTFAIL(app_key, td, sptr,
- "%s: value not given (%s:%d)",
- td->name, __FILE__, __LINE__);
- return -1;
- }
-
- value = *(const long *)sptr;
-
- if((value >= 0 && value <= 65535)) {
- /* Constraint check succeeded */
- return 0;
- } else {
- _ASN_CTFAIL(app_key, td, sptr,
- "%s: constraint failed (%s:%d)",
- td->name, __FILE__, __LINE__);
- return -1;
- }
-}
-
-static asn_TYPE_member_t asn_MBR_UdpEntry_1[] = {
- { ATF_NOFLAGS, 0, offsetof(struct UdpEntry, udpLocalAddress),
- (ASN_TAG_CLASS_APPLICATION | (0 << 2)),
- 0,
- &asn_DEF_IpAddress,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "udpLocalAddress"
- },
- { ATF_NOFLAGS, 0, offsetof(struct UdpEntry, udpLocalPort),
- (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
- 0,
- &asn_DEF_NativeInteger,
- memb_udpLocalPort_constraint_1,
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "udpLocalPort"
- },
-};
-static ber_tlv_tag_t asn_DEF_UdpEntry_tags_1[] = {
- (ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
-};
-static asn_TYPE_tag2member_t asn_MAP_UdpEntry_tag2el_1[] = {
- { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 1, 0, 0 }, /* udpLocalPort at 253 */
- { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 0, 0, 0 } /* udpLocalAddress at 251 */
-};
-static asn_SEQUENCE_specifics_t asn_SPC_UdpEntry_specs_1 = {
- sizeof(struct UdpEntry),
- offsetof(struct UdpEntry, _asn_ctx),
- asn_MAP_UdpEntry_tag2el_1,
- 2, /* Count of tags in the map */
- 0, 0, 0, /* Optional elements (not needed) */
- -1, /* Start extensions */
- -1 /* Stop extensions */
-};
-asn_TYPE_descriptor_t asn_DEF_UdpEntry = {
- "UdpEntry",
- "UdpEntry",
- SEQUENCE_free,
- SEQUENCE_print,
- SEQUENCE_constraint,
- SEQUENCE_decode_ber,
- SEQUENCE_encode_der,
- SEQUENCE_decode_xer,
- SEQUENCE_encode_xer,
- 0, 0, /* No PER support, use "-gen-PER" to enable */
- 0, /* Use generic outmost tag fetcher */
- asn_DEF_UdpEntry_tags_1,
- sizeof(asn_DEF_UdpEntry_tags_1)
- /sizeof(asn_DEF_UdpEntry_tags_1[0]), /* 1 */
- asn_DEF_UdpEntry_tags_1, /* Same as above */
- sizeof(asn_DEF_UdpEntry_tags_1)
- /sizeof(asn_DEF_UdpEntry_tags_1[0]), /* 1 */
- 0, /* No PER visible constraints */
- asn_MBR_UdpEntry_1,
- 2, /* Elements count */
- &asn_SPC_UdpEntry_specs_1 /* Additional specs */
-};
-
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1213-MIB"
- * found in "RFC1213-MIB.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#ifndef _UdpEntry_H_
-#define _UdpEntry_H_
-
-
-#include <asn_application.h>
-
-/* Including external dependencies */
-#include "IpAddress.h"
-#include <NativeInteger.h>
-#include <constr_SEQUENCE.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* UdpEntry */
-typedef struct UdpEntry {
- IpAddress_t udpLocalAddress;
- long udpLocalPort;
-
- /* Context for parsing across buffer boundaries */
- asn_struct_ctx_t _asn_ctx;
-} UdpEntry_t;
-
-/* Implementation */
-extern asn_TYPE_descriptor_t asn_DEF_UdpEntry;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _UdpEntry_H_ */
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1157-SNMP"
- * found in "RFC1157-SNMP.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#include <asn_internal.h>
-
-#include "VarBind.h"
-
-static asn_TYPE_member_t asn_MBR_VarBind_1[] = {
- { ATF_NOFLAGS, 0, offsetof(struct VarBind, name),
- (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)),
- 0,
- &asn_DEF_ObjectName,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "name"
- },
- { ATF_NOFLAGS, 0, offsetof(struct VarBind, value),
- -1 /* Ambiguous tag (CHOICE?) */,
- 0,
- &asn_DEF_ObjectSyntax,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- "value"
- },
-};
-static ber_tlv_tag_t asn_DEF_VarBind_tags_1[] = {
- (ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
-};
-static asn_TYPE_tag2member_t asn_MAP_VarBind_tag2el_1[] = {
- { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 1, 0, 0 }, /* number at 73 */
- { (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 1, 0, 0 }, /* string at 76 */
- { (ASN_TAG_CLASS_UNIVERSAL | (5 << 2)), 1, 0, 0 }, /* empty at 82 */
- { (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)), 0, 0, 1 }, /* name at 133 */
- { (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)), 1, -1, 0 }, /* object at 79 */
- { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 1, 0, 0 }, /* internet at 113 */
- { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 1, 0, 0 }, /* counter at 91 */
- { (ASN_TAG_CLASS_APPLICATION | (2 << 2)), 1, 0, 0 }, /* gauge at 94 */
- { (ASN_TAG_CLASS_APPLICATION | (3 << 2)), 1, 0, 0 }, /* ticks at 97 */
- { (ASN_TAG_CLASS_APPLICATION | (4 << 2)), 1, 0, 0 } /* arbitrary at 104 */
-};
-static asn_SEQUENCE_specifics_t asn_SPC_VarBind_specs_1 = {
- sizeof(struct VarBind),
- offsetof(struct VarBind, _asn_ctx),
- asn_MAP_VarBind_tag2el_1,
- 10, /* Count of tags in the map */
- 0, 0, 0, /* Optional elements (not needed) */
- -1, /* Start extensions */
- -1 /* Stop extensions */
-};
-asn_TYPE_descriptor_t asn_DEF_VarBind = {
- "VarBind",
- "VarBind",
- SEQUENCE_free,
- SEQUENCE_print,
- SEQUENCE_constraint,
- SEQUENCE_decode_ber,
- SEQUENCE_encode_der,
- SEQUENCE_decode_xer,
- SEQUENCE_encode_xer,
- 0, 0, /* No PER support, use "-gen-PER" to enable */
- 0, /* Use generic outmost tag fetcher */
- asn_DEF_VarBind_tags_1,
- sizeof(asn_DEF_VarBind_tags_1)
- /sizeof(asn_DEF_VarBind_tags_1[0]), /* 1 */
- asn_DEF_VarBind_tags_1, /* Same as above */
- sizeof(asn_DEF_VarBind_tags_1)
- /sizeof(asn_DEF_VarBind_tags_1[0]), /* 1 */
- 0, /* No PER visible constraints */
- asn_MBR_VarBind_1,
- 2, /* Elements count */
- &asn_SPC_VarBind_specs_1 /* Additional specs */
-};
-
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1157-SNMP"
- * found in "RFC1157-SNMP.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#ifndef _VarBind_H_
-#define _VarBind_H_
-
-
-#include <asn_application.h>
-
-/* Including external dependencies */
-#include "ObjectName.h"
-#include "ObjectSyntax.h"
-#include <constr_SEQUENCE.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* VarBind */
-typedef struct VarBind {
- ObjectName_t name;
- ObjectSyntax_t value;
-
- /* Context for parsing across buffer boundaries */
- asn_struct_ctx_t _asn_ctx;
-} VarBind_t;
-
-/* Implementation */
-extern asn_TYPE_descriptor_t asn_DEF_VarBind;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _VarBind_H_ */
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1157-SNMP"
- * found in "RFC1157-SNMP.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#include <asn_internal.h>
-
-#include "VarBindList.h"
-
-static asn_TYPE_member_t asn_MBR_VarBindList_1[] = {
- { ATF_POINTER, 0, 0,
- (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)),
- 0,
- &asn_DEF_VarBind,
- 0, /* Defer constraints checking to the member type */
- 0, /* PER is not compiled, use -gen-PER */
- 0,
- ""
- },
-};
-static ber_tlv_tag_t asn_DEF_VarBindList_tags_1[] = {
- (ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
-};
-static asn_SET_OF_specifics_t asn_SPC_VarBindList_specs_1 = {
- sizeof(struct VarBindList),
- offsetof(struct VarBindList, _asn_ctx),
- 0, /* XER encoding is XMLDelimitedItemList */
-};
-asn_TYPE_descriptor_t asn_DEF_VarBindList = {
- "VarBindList",
- "VarBindList",
- SEQUENCE_OF_free,
- SEQUENCE_OF_print,
- SEQUENCE_OF_constraint,
- SEQUENCE_OF_decode_ber,
- SEQUENCE_OF_encode_der,
- SEQUENCE_OF_decode_xer,
- SEQUENCE_OF_encode_xer,
- 0, 0, /* No PER support, use "-gen-PER" to enable */
- 0, /* Use generic outmost tag fetcher */
- asn_DEF_VarBindList_tags_1,
- sizeof(asn_DEF_VarBindList_tags_1)
- /sizeof(asn_DEF_VarBindList_tags_1[0]), /* 1 */
- asn_DEF_VarBindList_tags_1, /* Same as above */
- sizeof(asn_DEF_VarBindList_tags_1)
- /sizeof(asn_DEF_VarBindList_tags_1[0]), /* 1 */
- 0, /* No PER visible constraints */
- asn_MBR_VarBindList_1,
- 1, /* Single element */
- &asn_SPC_VarBindList_specs_1 /* Additional specs */
-};
-
+++ /dev/null
-/*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
- * From ASN.1 module "RFC1157-SNMP"
- * found in "RFC1157-SNMP.asn1"
- * `asn1c -fskeletons-copy`
- */
-
-#ifndef _VarBindList_H_
-#define _VarBindList_H_
-
-
-#include <asn_application.h>
-
-/* Including external dependencies */
-#include <asn_SEQUENCE_OF.h>
-#include <constr_SEQUENCE_OF.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Forward declarations */
-struct VarBind;
-
-/* VarBindList */
-typedef struct VarBindList {
- A_SEQUENCE_OF(struct VarBind) list;
-
- /* Context for parsing across buffer boundaries */
- asn_struct_ctx_t _asn_ctx;
-} VarBindList_t;
-
-/* Implementation */
-extern asn_TYPE_descriptor_t asn_DEF_VarBindList;
-
-#ifdef __cplusplus
-}
-#endif
-
-/* Referred external types */
-#include "VarBind.h"
-
-#endif /* _VarBindList_H_ */
+++ /dev/null
-/*-
- * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-#include <asn_internal.h>
-#include <asn_SEQUENCE_OF.h>
-
-typedef A_SEQUENCE_OF(void) asn_sequence;
-
-void
-asn_sequence_del(void *asn_sequence_of_x, int number, int _do_free) {
- asn_sequence *as = (asn_sequence *)asn_sequence_of_x;
-
- if(as) {
- void *ptr;
- int n;
-
- if(number < 0 || number >= as->count)
- return; /* Nothing to delete */
-
- if(_do_free && as->free) {
- ptr = as->array[number];
- } else {
- ptr = 0;
- }
-
- /*
- * Shift all elements to the left to hide the gap.
- */
- --as->count;
- for(n = number; n < as->count; n++)
- as->array[n] = as->array[n+1];
-
- /*
- * Invoke the third-party function only when the state
- * of the parent structure is consistent.
- */
- if(ptr) as->free(ptr);
- }
-}
-
+++ /dev/null
-/*-
- * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-#ifndef ASN_SEQUENCE_OF_H
-#define ASN_SEQUENCE_OF_H
-
-#include <asn_SET_OF.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * SEQUENCE OF is the same as SET OF with a tiny difference:
- * the delete operation preserves the initial order of elements
- * and thus MAY operate in non-constant time.
- */
-#define A_SEQUENCE_OF(type) A_SET_OF(type)
-
-#define ASN_SEQUENCE_ADD(headptr, ptr) \
- asn_sequence_add((headptr), (ptr))
-
-/***********************************************
- * Implementation of the SEQUENCE OF structure.
- */
-
-#define asn_sequence_add asn_set_add
-#define asn_sequence_empty asn_set_empty
-
-/*
- * Delete the element from the set by its number (base 0).
- * This is NOT a constant-time operation.
- * The order of elements is preserved.
- * If _do_free is given AND the (*free) is initialized, the element
- * will be freed using the custom (*free) function as well.
- */
-void asn_sequence_del(void *asn_sequence_of_x, int number, int _do_free);
-
-/*
- * Cope with different conversions requirements to/from void in C and C++.
- * This is mostly useful for support library.
- */
-typedef A_SEQUENCE_OF(void) asn_anonymous_sequence_;
-#define _A_SEQUENCE_FROM_VOID(ptr) ((asn_anonymous_sequence_ *)(ptr))
-#define _A_CSEQUENCE_FROM_VOID(ptr) ((const asn_anonymous_sequence_ *)(ptr))
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* ASN_SEQUENCE_OF_H */
+++ /dev/null
-/*-
- * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-#include <asn_internal.h>
-#include <asn_SET_OF.h>
-#include <errno.h>
-
-/*
- * Add another element into the set.
- */
-int
-asn_set_add(void *asn_set_of_x, void *ptr) {
- asn_anonymous_set_ *as = _A_SET_FROM_VOID(asn_set_of_x);
-
- if(as == 0 || ptr == 0) {
- errno = EINVAL; /* Invalid arguments */
- return -1;
- }
-
- /*
- * Make sure there's enough space to insert an element.
- */
- if(as->count == as->size) {
- int _newsize = as->size ? (as->size << 1) : 4;
- void *_new_arr;
- _new_arr = REALLOC(as->array, _newsize * sizeof(as->array[0]));
- if(_new_arr) {
- as->array = (void **)_new_arr;
- as->size = _newsize;
- } else {
- /* ENOMEM */
- return -1;
- }
- }
-
- as->array[as->count++] = ptr;
-
- return 0;
-}
-
-void
-asn_set_del(void *asn_set_of_x, int number, int _do_free) {
- asn_anonymous_set_ *as = _A_SET_FROM_VOID(asn_set_of_x);
-
- if(as) {
- void *ptr;
- if(number < 0 || number >= as->count)
- return;
-
- if(_do_free && as->free) {
- ptr = as->array[number];
- } else {
- ptr = 0;
- }
-
- as->array[number] = as->array[--as->count];
-
- /*
- * Invoke the third-party function only when the state
- * of the parent structure is consistent.
- */
- if(ptr) as->free(ptr);
- }
-}
-
-/*
- * Free the contents of the set, do not free the set itself.
- */
-void
-asn_set_empty(void *asn_set_of_x) {
- asn_anonymous_set_ *as = _A_SET_FROM_VOID(asn_set_of_x);
-
- if(as) {
- if(as->array) {
- if(as->free) {
- while(as->count--)
- as->free(as->array[as->count]);
- }
- FREEMEM(as->array);
- as->array = 0;
- }
- as->count = 0;
- as->size = 0;
- }
-
-}
-
+++ /dev/null
-/*-
- * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-#ifndef ASN_SET_OF_H
-#define ASN_SET_OF_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define A_SET_OF(type) \
- struct { \
- type **array; \
- int count; /* Meaningful size */ \
- int size; /* Allocated size */ \
- void (*free)(type *); \
- }
-
-#define ASN_SET_ADD(headptr, ptr) \
- asn_set_add((headptr), (ptr))
-
-/*******************************************
- * Implementation of the SET OF structure.
- */
-
-/*
- * Add another structure into the set by its pointer.
- * RETURN VALUES:
- * 0 for success and -1/errno for failure.
- */
-int asn_set_add(void *asn_set_of_x, void *ptr);
-
-/*
- * Delete the element from the set by its number (base 0).
- * This is a constant-time operation. The order of elements before the
- * deleted ones is guaranteed, the order of elements after the deleted
- * one is NOT guaranteed.
- * If _do_free is given AND the (*free) is initialized, the element
- * will be freed using the custom (*free) function as well.
- */
-void asn_set_del(void *asn_set_of_x, int number, int _do_free);
-
-/*
- * Empty the contents of the set. Will free the elements, if (*free) is given.
- * Will NOT free the set itself.
- */
-void asn_set_empty(void *asn_set_of_x);
-
-/*
- * Cope with different conversions requirements to/from void in C and C++.
- * This is mostly useful for support library.
- */
-typedef A_SET_OF(void) asn_anonymous_set_;
-#define _A_SET_FROM_VOID(ptr) ((asn_anonymous_set_ *)(ptr))
-#define _A_CSET_FROM_VOID(ptr) ((const asn_anonymous_set_ *)(ptr))
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* ASN_SET_OF_H */
+++ /dev/null
-/*-
- * Copyright (c) 2004, 2006 Lev Walkin <vlm@lionet.info>. All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-/*
- * Application-level ASN.1 callbacks.
- */
-#ifndef _ASN_APPLICATION_H_
-#define _ASN_APPLICATION_H_
-
-#include "asn_system.h" /* for platform-dependent types */
-#include "asn_codecs.h" /* for ASN.1 codecs specifics */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Generic type of an application-defined callback to return various
- * types of data to the application.
- * EXPECTED RETURN VALUES:
- * -1: Failed to consume bytes. Abort the mission.
- * Non-negative return values indicate success, and ignored.
- */
-typedef int (asn_app_consume_bytes_f)(const void *buffer, size_t size,
- void *application_specific_key);
-
-/*
- * A callback of this type is called whenever constraint validation fails
- * on some ASN.1 type. See "constraints.h" for more details on constraint
- * validation.
- * This callback specifies a descriptor of the ASN.1 type which failed
- * the constraint check, as well as human readable message on what
- * particular constraint has failed.
- */
-typedef void (asn_app_constraint_failed_f)(void *application_specific_key,
- struct asn_TYPE_descriptor_s *type_descriptor_which_failed,
- const void *structure_which_failed_ptr,
- const char *error_message_format, ...) GCC_PRINTFLIKE(4, 5);
-
-#ifdef __cplusplus
-}
-#endif
-
-#include "constr_TYPE.h" /* for asn_TYPE_descriptor_t */
-
-#endif /* _ASN_APPLICATION_H_ */
+++ /dev/null
-/*-
- * Copyright (c) 2003, 2004, 2005 Lev Walkin <vlm@lionet.info>.
- * All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-#ifndef _ASN_CODECS_H_
-#define _ASN_CODECS_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct asn_TYPE_descriptor_s; /* Forward declaration */
-
-/*
- * This structure defines a set of parameters that may be passed
- * to every ASN.1 encoder or decoder function.
- * WARNING: if max_stack_size member is set, and you are calling the
- * function pointers of the asn_TYPE_descriptor_t directly,
- * this structure must be ALLOCATED ON THE STACK!
- * If you can't always satisfy this requirement, use ber_decode(),
- * xer_decode() and uper_decode() functions instead.
- */
-typedef struct asn_codec_ctx_s {
- /*
- * Limit the decoder routines to use no (much) more stack than a given
- * number of bytes. Most of decoders are stack-based, and this
- * would protect against stack overflows if the number of nested
- * encodings is high.
- * The OCTET STRING, BIT STRING and ANY BER decoders are heap-based,
- * and are safe from this kind of overflow.
- * A value from getrlimit(RLIMIT_STACK) may be used to initialize
- * this variable. Be careful in multithreaded environments, as the
- * stack size is rather limited.
- */
- size_t max_stack_size; /* 0 disables stack bounds checking */
-} asn_codec_ctx_t;
-
-/*
- * Type of the return value of the encoding functions (der_encode, xer_encode).
- */
-typedef struct asn_enc_rval_s {
- /*
- * Number of bytes encoded.
- * -1 indicates failure to encode the structure.
- * In this case, the members below this one are meaningful.
- */
- ssize_t encoded;
-
- /*
- * Members meaningful when (encoded == -1), for post mortem analysis.
- */
-
- /* Type which cannot be encoded */
- struct asn_TYPE_descriptor_s *failed_type;
-
- /* Pointer to the structure of that type */
- void *structure_ptr;
-} asn_enc_rval_t;
-#define _ASN_ENCODE_FAILED do { \
- asn_enc_rval_t tmp_error; \
- tmp_error.encoded = -1; \
- tmp_error.failed_type = td; \
- tmp_error.structure_ptr = sptr; \
- ASN_DEBUG("Failed to encode element %s", td->name); \
- return tmp_error; \
-} while(0)
-#define _ASN_ENCODED_OK(rval) do { \
- rval.structure_ptr = 0; \
- rval.failed_type = 0; \
- return rval; \
-} while(0)
-
-/*
- * Type of the return value of the decoding functions (ber_decode, xer_decode)
- *
- * Please note that the number of consumed bytes is ALWAYS meaningful,
- * even if code==RC_FAIL. This is to indicate the number of successfully
- * decoded bytes, hence providing a possibility to fail with more diagnostics
- * (i.e., print the offending remainder of the buffer).
- */
-enum asn_dec_rval_code_e {
- RC_OK, /* Decoded successfully */
- RC_WMORE, /* More data expected, call again */
- RC_FAIL /* Failure to decode data */
-};
-typedef struct asn_dec_rval_s {
- enum asn_dec_rval_code_e code; /* Result code */
- size_t consumed; /* Number of bytes consumed */
-} asn_dec_rval_t;
-#define _ASN_DECODE_FAILED do { \
- asn_dec_rval_t tmp_error; \
- tmp_error.code = RC_FAIL; \
- tmp_error.consumed = 0; \
- ASN_DEBUG("Failed to decode element %s", td->name); \
- return tmp_error; \
-} while(0)
-#define _ASN_DECODE_STARVED do { \
- asn_dec_rval_t tmp_error; \
- tmp_error.code = RC_WMORE; \
- tmp_error.consumed = 0; \
- return tmp_error; \
-} while(0)
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _ASN_CODECS_H_ */
+++ /dev/null
-/*-
- * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-#include <asn_internal.h>
-#include <asn_codecs_prim.h>
-#include <errno.h>
-
-/*
- * Decode an always-primitive type.
- */
-asn_dec_rval_t
-ber_decode_primitive(asn_codec_ctx_t *opt_codec_ctx,
- asn_TYPE_descriptor_t *td,
- void **sptr, const void *buf_ptr, size_t size, int tag_mode) {
- ASN__PRIMITIVE_TYPE_t *st = (ASN__PRIMITIVE_TYPE_t *)*sptr;
- asn_dec_rval_t rval;
- ber_tlv_len_t length;
-
- /*
- * If the structure is not there, allocate it.
- */
- if(st == NULL) {
- st = (ASN__PRIMITIVE_TYPE_t *)CALLOC(1, sizeof(*st));
- if(st == NULL) _ASN_DECODE_FAILED;
- *sptr = (void *)st;
- }
-
- ASN_DEBUG("Decoding %s as plain primitive (tm=%d)",
- td->name, tag_mode);
-
- /*
- * Check tags and extract value length.
- */
- rval = ber_check_tags(opt_codec_ctx, td, 0, buf_ptr, size,
- tag_mode, 0, &length, 0);
- if(rval.code != RC_OK)
- return rval;
-
- ASN_DEBUG("%s length is %d bytes", td->name, (int)length);
-
- /*
- * Make sure we have this length.
- */
- buf_ptr = ((const char *)buf_ptr) + rval.consumed;
- size -= rval.consumed;
- if(length > (ber_tlv_len_t)size) {
- rval.code = RC_WMORE;
- rval.consumed = 0;
- return rval;
- }
-
- st->size = (int)length;
- /* The following better be optimized away. */
- if(sizeof(st->size) != sizeof(length)
- && (ber_tlv_len_t)st->size != length) {
- st->size = 0;
- _ASN_DECODE_FAILED;
- }
-
- st->buf = (uint8_t *)MALLOC(length + 1);
- if(!st->buf) {
- st->size = 0;
- _ASN_DECODE_FAILED;
- }
-
- memcpy(st->buf, buf_ptr, length);
- st->buf[length] = '\0'; /* Just in case */
-
- rval.code = RC_OK;
- rval.consumed += length;
-
- ASN_DEBUG("Took %ld/%ld bytes to encode %s",
- (long)rval.consumed,
- (long)length, td->name);
-
- return rval;
-}
-
-/*
- * Encode an always-primitive type using DER.
- */
-asn_enc_rval_t
-der_encode_primitive(asn_TYPE_descriptor_t *td, void *sptr,
- int tag_mode, ber_tlv_tag_t tag,
- asn_app_consume_bytes_f *cb, void *app_key) {
- asn_enc_rval_t erval;
- ASN__PRIMITIVE_TYPE_t *st = (ASN__PRIMITIVE_TYPE_t *)sptr;
-
- ASN_DEBUG("%s %s as a primitive type (tm=%d)",
- cb?"Encoding":"Estimating", td->name, tag_mode);
-
- erval.encoded = der_write_tags(td, st->size, tag_mode, 0, tag,
- cb, app_key);
- ASN_DEBUG("%s wrote tags %d", td->name, (int)erval.encoded);
- if(erval.encoded == -1) {
- erval.failed_type = td;
- erval.structure_ptr = sptr;
- return erval;
- }
-
- if(cb && st->buf) {
- if(cb(st->buf, st->size, app_key) < 0) {
- erval.encoded = -1;
- erval.failed_type = td;
- erval.structure_ptr = sptr;
- return erval;
- }
- } else {
- assert(st->buf || st->size == 0);
- }
-
- erval.encoded += st->size;
- _ASN_ENCODED_OK(erval);
-}
-
-void
-ASN__PRIMITIVE_TYPE_free(asn_TYPE_descriptor_t *td, void *sptr,
- int contents_only) {
- ASN__PRIMITIVE_TYPE_t *st = (ASN__PRIMITIVE_TYPE_t *)sptr;
-
- if(!td || !sptr)
- return;
-
- ASN_DEBUG("Freeing %s as a primitive type", td->name);
-
- if(st->buf)
- FREEMEM(st->buf);
-
- if(!contents_only)
- FREEMEM(st);
-}
-
-
-/*
- * Local internal type passed around as an argument.
- */
-struct xdp_arg_s {
- asn_TYPE_descriptor_t *type_descriptor;
- void *struct_key;
- xer_primitive_body_decoder_f *prim_body_decoder;
- int decoded_something;
- int want_more;
-};
-
-
-static int
-xer_decode__unexpected_tag(void *key, const void *chunk_buf, size_t chunk_size) {
- struct xdp_arg_s *arg = (struct xdp_arg_s *)key;
- enum xer_pbd_rval bret;
-
- if(arg->decoded_something) {
- if(xer_is_whitespace(chunk_buf, chunk_size))
- return 0; /* Skip it. */
- /*
- * Decoding was done once already. Prohibit doing it again.
- */
- return -1;
- }
-
- bret = arg->prim_body_decoder(arg->type_descriptor,
- arg->struct_key, chunk_buf, chunk_size);
- switch(bret) {
- case XPBD_SYSTEM_FAILURE:
- case XPBD_DECODER_LIMIT:
- case XPBD_BROKEN_ENCODING:
- break;
- case XPBD_BODY_CONSUMED:
- /* Tag decoded successfully */
- arg->decoded_something = 1;
- /* Fall through */
- case XPBD_NOT_BODY_IGNORE: /* Safe to proceed further */
- return 0;
- }
-
- return -1;
-}
-
-static ssize_t
-xer_decode__body(void *key, const void *chunk_buf, size_t chunk_size, int have_more) {
- struct xdp_arg_s *arg = (struct xdp_arg_s *)key;
- enum xer_pbd_rval bret;
-
- if(arg->decoded_something) {
- if(xer_is_whitespace(chunk_buf, chunk_size))
- return chunk_size;
- /*
- * Decoding was done once already. Prohibit doing it again.
- */
- return -1;
- }
-
- if(!have_more) {
- /*
- * If we've received something like "1", we can't really
- * tell whether it is really `1` or `123`, until we know
- * that there is no more data coming.
- * The have_more argument will be set to 1 once something
- * like this is available to the caller of this callback:
- * "1<tag_start..."
- */
- arg->want_more = 1;
- return -1;
- }
-
- bret = arg->prim_body_decoder(arg->type_descriptor,
- arg->struct_key, chunk_buf, chunk_size);
- switch(bret) {
- case XPBD_SYSTEM_FAILURE:
- case XPBD_DECODER_LIMIT:
- case XPBD_BROKEN_ENCODING:
- break;
- case XPBD_BODY_CONSUMED:
- /* Tag decoded successfully */
- arg->decoded_something = 1;
- /* Fall through */
- case XPBD_NOT_BODY_IGNORE: /* Safe to proceed further */
- return chunk_size;
- }
-
- return -1;
-}
-
-
-asn_dec_rval_t
-xer_decode_primitive(asn_codec_ctx_t *opt_codec_ctx,
- asn_TYPE_descriptor_t *td,
- void **sptr,
- size_t struct_size,
- const char *opt_mname,
- const void *buf_ptr, size_t size,
- xer_primitive_body_decoder_f *prim_body_decoder
-) {
- const char *xml_tag = opt_mname ? opt_mname : td->xml_tag;
- asn_struct_ctx_t s_ctx;
- struct xdp_arg_s s_arg;
- asn_dec_rval_t rc;
-
- /*
- * Create the structure if does not exist.
- */
- if(!*sptr) {
- *sptr = CALLOC(1, struct_size);
- if(!*sptr) _ASN_DECODE_FAILED;
- }
-
- memset(&s_ctx, 0, sizeof(s_ctx));
- s_arg.type_descriptor = td;
- s_arg.struct_key = *sptr;
- s_arg.prim_body_decoder = prim_body_decoder;
- s_arg.decoded_something = 0;
- s_arg.want_more = 0;
-
- rc = xer_decode_general(opt_codec_ctx, &s_ctx, &s_arg,
- xml_tag, buf_ptr, size,
- xer_decode__unexpected_tag, xer_decode__body);
- switch(rc.code) {
- case RC_OK:
- if(!s_arg.decoded_something) {
- char ch;
- ASN_DEBUG("Primitive body is not recognized, "
- "supplying empty one");
- /*
- * Decoding opportunity has come and gone.
- * Where's the result?
- * Try to feed with empty body, see if it eats it.
- */
- if(prim_body_decoder(s_arg.type_descriptor,
- s_arg.struct_key, &ch, 0)
- != XPBD_BODY_CONSUMED) {
- /*
- * This decoder does not like empty stuff.
- */
- _ASN_DECODE_FAILED;
- }
- }
- break;
- case RC_WMORE:
- /*
- * Redo the whole thing later.
- * We don't have a context to save intermediate parsing state.
- */
- rc.consumed = 0;
- break;
- case RC_FAIL:
- rc.consumed = 0;
- if(s_arg.want_more)
- rc.code = RC_WMORE;
- else
- _ASN_DECODE_FAILED;
- break;
- }
- return rc;
-}
-
+++ /dev/null
-/*-
- * Copyright (c) 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-#ifndef ASN_CODECS_PRIM_H
-#define ASN_CODECS_PRIM_H
-
-#include <asn_application.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct ASN__PRIMITIVE_TYPE_s {
- uint8_t *buf; /* Buffer with consecutive primitive encoding bytes */
- int size; /* Size of the buffer */
-} ASN__PRIMITIVE_TYPE_t; /* Do not use this type directly! */
-
-asn_struct_free_f ASN__PRIMITIVE_TYPE_free;
-ber_type_decoder_f ber_decode_primitive;
-der_type_encoder_f der_encode_primitive;
-
-/*
- * A callback specification for the xer_decode_primitive() function below.
- */
-enum xer_pbd_rval {
- XPBD_SYSTEM_FAILURE, /* System failure (memory shortage, etc) */
- XPBD_DECODER_LIMIT, /* Hit some decoder limitation or deficiency */
- XPBD_BROKEN_ENCODING, /* Encoding of a primitive body is broken */
- XPBD_NOT_BODY_IGNORE, /* Not a body format, but safe to ignore */
- XPBD_BODY_CONSUMED /* Body is recognized and consumed */
-};
-typedef enum xer_pbd_rval (xer_primitive_body_decoder_f)
- (asn_TYPE_descriptor_t *td, void *struct_ptr,
- const void *chunk_buf, size_t chunk_size);
-
-/*
- * Specific function to decode simple primitive types.
- * Also see xer_decode_general() in xer_decoder.h
- */
-asn_dec_rval_t xer_decode_primitive(asn_codec_ctx_t *opt_codec_ctx,
- asn_TYPE_descriptor_t *type_descriptor,
- void **struct_ptr, size_t struct_size,
- const char *opt_mname,
- const void *buf_ptr, size_t size,
- xer_primitive_body_decoder_f *prim_body_decoder
-);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* ASN_CODECS_PRIM_H */
+++ /dev/null
-/*-
- * Copyright (c) 2003, 2004, 2005 Lev Walkin <vlm@lionet.info>.
- * All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-/*
- * Declarations internally useful for the ASN.1 support code.
- */
-#ifndef _ASN_INTERNAL_H_
-#define _ASN_INTERNAL_H_
-
-#include "asn_application.h" /* Application-visible API */
-
-#ifndef __NO_ASSERT_H__ /* Include assert.h only for internal use. */
-#include <assert.h> /* for assert() macro */
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Environment version might be used to avoid running with the old library */
-#define ASN1C_ENVIRONMENT_VERSION 920 /* Compile-time version */
-int get_asn1c_environment_version(void); /* Run-time version */
-
-#define CALLOC(nmemb, size) calloc(nmemb, size)
-#define MALLOC(size) malloc(size)
-#define REALLOC(oldptr, size) realloc(oldptr, size)
-#define FREEMEM(ptr) free(ptr)
-
-/*
- * A macro for debugging the ASN.1 internals.
- * You may enable or override it.
- */
-#ifndef ASN_DEBUG /* If debugging code is not defined elsewhere... */
-#if EMIT_ASN_DEBUG == 1 /* And it was asked to emit this code... */
-#ifdef __GNUC__
-#define ASN_DEBUG(fmt, args...) do { \
- fprintf(stderr, fmt, ##args); \
- fprintf(stderr, " (%s:%d)\n", \
- __FILE__, __LINE__); \
- } while(0)
-#else /* !__GNUC__ */
-void ASN_DEBUG_f(const char *fmt, ...);
-#define ASN_DEBUG ASN_DEBUG_f
-#endif /* __GNUC__ */
-#else /* EMIT_ASN_DEBUG != 1 */
-static inline void ASN_DEBUG(const char *fmt, ...) { (void)fmt; }
-#endif /* EMIT_ASN_DEBUG */
-#endif /* ASN_DEBUG */
-
-/*
- * Invoke the application-supplied callback and fail, if something is wrong.
- */
-#define __ASN_E_cbc(buf, size) (cb((buf), (size), app_key) < 0)
-#define _ASN_E_CALLBACK(foo) do { \
- if(foo) goto cb_failed; \
- } while(0)
-#define _ASN_CALLBACK(buf, size) \
- _ASN_E_CALLBACK(__ASN_E_cbc(buf, size))
-#define _ASN_CALLBACK2(buf1, size1, buf2, size2) \
- _ASN_E_CALLBACK(__ASN_E_cbc(buf1, size1) || __ASN_E_cbc(buf2, size2))
-#define _ASN_CALLBACK3(buf1, size1, buf2, size2, buf3, size3) \
- _ASN_E_CALLBACK(__ASN_E_cbc(buf1, size1) \
- || __ASN_E_cbc(buf2, size2) \
- || __ASN_E_cbc(buf3, size3))
-
-#define _i_ASN_TEXT_INDENT(nl, level) do { \
- int __level = (level); \
- int __nl = ((nl) != 0); \
- int __i; \
- if(__nl) _ASN_CALLBACK("\n", 1); \
- for(__i = 0; __i < __level; __i++) \
- _ASN_CALLBACK(" ", 4); \
- er.encoded += __nl + 4 * __level; \
-} while(0)
-
-#define _i_INDENT(nl) do { \
- int __i; \
- if((nl) && cb("\n", 1, app_key) < 0) return -1; \
- for(__i = 0; __i < ilevel; __i++) \
- if(cb(" ", 4, app_key) < 0) return -1; \
-} while(0)
-
-/*
- * Check stack against overflow, if limit is set.
- */
-#define _ASN_DEFAULT_STACK_MAX (30000)
-static inline int
-_ASN_STACK_OVERFLOW_CHECK(asn_codec_ctx_t *ctx) {
- if(ctx && ctx->max_stack_size) {
-
- /* ctx MUST be allocated on the stack */
- ptrdiff_t usedstack = ((char *)ctx - (char *)&ctx);
- if(usedstack > 0) usedstack = -usedstack; /* grows up! */
-
- /* double negative required to avoid int wrap-around */
- if(usedstack < -(ptrdiff_t)ctx->max_stack_size) {
- ASN_DEBUG("Stack limit %ld reached",
- (long)ctx->max_stack_size);
- return -1;
- }
- }
- return 0;
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _ASN_INTERNAL_H_ */
+++ /dev/null
-/*-
- * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-/*
- * Miscellaneous system-dependent types.
- */
-#ifndef _ASN_SYSTEM_H_
-#define _ASN_SYSTEM_H_
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <stdio.h> /* For snprintf(3) */
-#include <stdlib.h> /* For *alloc(3) */
-#include <string.h> /* For memcpy(3) */
-#include <sys/types.h> /* For size_t */
-#include <stdarg.h> /* For va_start */
-#include <stddef.h> /* for offsetof and ptrdiff_t */
-
-#ifdef WIN32
-
-#include <malloc.h>
-#include <stdint.h>
-#define snprintf _snprintf
-#define vsnprintf _vsnprintf
-
-#ifdef _MSC_VER /* MSVS.Net */
-#ifndef __cplusplus
-#define inline __inline
-#endif
-#define ssize_t SSIZE_T
-typedef char int8_t;
-typedef short int16_t;
-typedef int int32_t;
-typedef unsigned char uint8_t;
-typedef unsigned short uint16_t;
-typedef unsigned int uint32_t;
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#include <float.h>
-#define isnan _isnan
-#define finite _finite
-#define copysign _copysign
-#define ilogb _logb
-#endif /* _MSC_VER */
-
-#else /* !WIN32 */
-
-#if defined(__vxworks)
-#include <types/vxTypes.h>
-#else /* !defined(__vxworks) */
-
-#include <inttypes.h> /* C99 specifies this file */
-/*
- * 1. Earlier FreeBSD version didn't have <stdint.h>,
- * but <inttypes.h> was present.
- * 2. Sun Solaris requires <alloca.h> for alloca(3),
- * but does not have <stdint.h>.
- */
-#if (!defined(__FreeBSD__) || !defined(_SYS_INTTYPES_H_))
-#if defined(sun)
-#include <alloca.h> /* For alloca(3) */
-#include <ieeefp.h> /* for finite(3) */
-#elif defined(__hpux)
-#ifdef __GNUC__
-#include <alloca.h> /* For alloca(3) */
-#else /* !__GNUC__ */
-#define inline
-#endif /* __GNUC__ */
-#else
-#include <stdint.h> /* SUSv2+ and C99 specify this file, for uintXX_t */
-#endif /* defined(sun) */
-#endif
-
-#endif /* defined(__vxworks) */
-
-#endif /* WIN32 */
-
-#if __GNUC__ >= 3
-#ifndef GCC_PRINTFLIKE
-#define GCC_PRINTFLIKE(fmt,var) __attribute__((format(printf,fmt,var)))
-#endif
-#else
-#ifndef GCC_PRINTFLIKE
-#define GCC_PRINTFLIKE(fmt,var) /* nothing */
-#endif
-#endif
-
-#ifndef offsetof /* If not defined by <stddef.h> */
-#define offsetof(s, m) ((ptrdiff_t)&(((s *)0)->m) - (ptrdiff_t)((s *)0))
-#endif /* offsetof */
-
-#ifndef MIN /* Suitable for comparing primitive types (integers) */
-#if defined(__GNUC__)
-#define MIN(a,b) ({ __typeof a _a = a; __typeof b _b = b; \
- ((_a)<(_b)?(_a):(_b)); })
-#else /* !__GNUC__ */
-#define MIN(a,b) ((a)<(b)?(a):(b)) /* Unsafe variant */
-#endif /* __GNUC__ */
-#endif /* MIN */
-
-#endif /* _ASN_SYSTEM_H_ */
+++ /dev/null
-/*-
- * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-#include <asn_internal.h>
-
-#undef ADVANCE
-#define ADVANCE(num_bytes) do { \
- size_t num = num_bytes; \
- ptr = ((const char *)ptr) + num; \
- size -= num; \
- consumed_myself += num; \
- } while(0)
-#undef RETURN
-#define RETURN(_code) do { \
- asn_dec_rval_t rval; \
- rval.code = _code; \
- if(opt_ctx) opt_ctx->step = step; /* Save context */ \
- if(_code == RC_OK || opt_ctx) \
- rval.consumed = consumed_myself; \
- else \
- rval.consumed = 0; /* Context-free */ \
- return rval; \
- } while(0)
-
-/*
- * The BER decoder of any type.
- */
-asn_dec_rval_t
-ber_decode(asn_codec_ctx_t *opt_codec_ctx,
- asn_TYPE_descriptor_t *type_descriptor,
- void **struct_ptr, const void *ptr, size_t size) {
- asn_codec_ctx_t s_codec_ctx;
-
- /*
- * Stack checker requires that the codec context
- * must be allocated on the stack.
- */
- if(opt_codec_ctx) {
- if(opt_codec_ctx->max_stack_size) {
- s_codec_ctx = *opt_codec_ctx;
- opt_codec_ctx = &s_codec_ctx;
- }
- } else {
- /* If context is not given, be security-conscious anyway */
- memset(&s_codec_ctx, 0, sizeof(s_codec_ctx));
- s_codec_ctx.max_stack_size = _ASN_DEFAULT_STACK_MAX;
- opt_codec_ctx = &s_codec_ctx;
- }
-
- /*
- * Invoke type-specific decoder.
- */
- return type_descriptor->ber_decoder(opt_codec_ctx, type_descriptor,
- struct_ptr, /* Pointer to the destination structure */
- ptr, size, /* Buffer and its size */
- 0 /* Default tag mode is 0 */
- );
-}
-
-/*
- * Check the set of <TL<TL<TL...>>> tags matches the definition.
- */
-asn_dec_rval_t
-ber_check_tags(asn_codec_ctx_t *opt_codec_ctx,
- asn_TYPE_descriptor_t *td, asn_struct_ctx_t *opt_ctx,
- const void *ptr, size_t size, int tag_mode, int last_tag_form,
- ber_tlv_len_t *last_length, int *opt_tlv_form) {
- ssize_t consumed_myself = 0;
- ssize_t tag_len;
- ssize_t len_len;
- ber_tlv_tag_t tlv_tag;
- ber_tlv_len_t tlv_len;
- ber_tlv_len_t limit_len = -1;
- int expect_00_terminators = 0;
- int tlv_constr = -1; /* If CHOICE, opt_tlv_form is not given */
- int step = opt_ctx ? opt_ctx->step : 0; /* Where we left previously */
- int tagno;
-
- /*
- * Make sure we didn't exceed the maximum stack size.
- */
- if(_ASN_STACK_OVERFLOW_CHECK(opt_codec_ctx))
- RETURN(RC_FAIL);
-
- /*
- * So what does all this implicit skip stuff mean?
- * Imagine two types,
- * A ::= [5] IMPLICIT T
- * B ::= [2] EXPLICIT T
- * Where T is defined as
- * T ::= [4] IMPLICIT SEQUENCE { ... }
- *
- * Let's say, we are starting to decode type A, given the
- * following TLV stream: <5> <0>. What does this mean?
- * It means that the type A contains type T which is,
- * in turn, empty.
- * Remember though, that we are still in A. We cannot
- * just pass control to the type T decoder. Why? Because
- * the type T decoder expects <4> <0>, not <5> <0>.
- * So, we must make sure we are going to receive <5> while
- * still in A, then pass control to the T decoder, indicating
- * that the tag <4> was implicitly skipped. The decoder of T
- * hence will be prepared to treat <4> as valid tag, and decode
- * it appropriately.
- */
-
- tagno = step /* Continuing where left previously */
- + (tag_mode==1?-1:0)
- ;
- ASN_DEBUG("ber_check_tags(%s, size=%ld, tm=%d, step=%d, tagno=%d)",
- td->name, (long)size, tag_mode, step, tagno);
- /* assert(td->tags_count >= 1) May not be the case for CHOICE or ANY */
-
- if(tag_mode == 0 && tagno == td->tags_count) {
- /*
- * This must be the _untagged_ ANY type,
- * which outermost tag isn't known in advance.
- * Fetch the tag and length separately.
- */
- tag_len = ber_fetch_tag(ptr, size, &tlv_tag);
- switch(tag_len) {
- case -1: RETURN(RC_FAIL);
- case 0: RETURN(RC_WMORE);
- }
- tlv_constr = BER_TLV_CONSTRUCTED(ptr);
- len_len = ber_fetch_length(tlv_constr,
- (const char *)ptr + tag_len, size - tag_len, &tlv_len);
- switch(len_len) {
- case -1: RETURN(RC_FAIL);
- case 0: RETURN(RC_WMORE);
- }
- ASN_DEBUG("Advancing %ld in ANY case",
- (long)(tag_len + len_len));
- ADVANCE(tag_len + len_len);
- } else {
- assert(tagno < td->tags_count); /* At least one loop */
- }
- for((void)tagno; tagno < td->tags_count; tagno++, step++) {
-
- /*
- * Fetch and process T from TLV.
- */
- tag_len = ber_fetch_tag(ptr, size, &tlv_tag);
- ASN_DEBUG("Fetching tag from {%p,%ld}: "
- "len %ld, step %d, tagno %d got %s",
- ptr, (long)size,
- (long)tag_len, step, tagno,
- ber_tlv_tag_string(tlv_tag));
- switch(tag_len) {
- case -1: RETURN(RC_FAIL);
- case 0: RETURN(RC_WMORE);
- }
-
- tlv_constr = BER_TLV_CONSTRUCTED(ptr);
-
- /*
- * If {I}, don't check anything.
- * If {I,B,C}, check B and C unless we're at I.
- */
- if(tag_mode != 0 && step == 0) {
- /*
- * We don't expect tag to match here.
- * It's just because we don't know how the tag
- * is supposed to look like.
- */
- } else {
- assert(tagno >= 0); /* Guaranteed by the code above */
- if(tlv_tag != td->tags[tagno]) {
- /*
- * Unexpected tag. Too bad.
- */
- ASN_DEBUG("Expected: %s, "
- "expectation failed (tn=%d, tm=%d)",
- ber_tlv_tag_string(td->tags[tagno]),
- tagno, tag_mode
- );
- RETURN(RC_FAIL);
- }
- }
-
- /*
- * Attention: if there are more tags expected,
- * ensure that the current tag is presented
- * in constructed form (it contains other tags!).
- * If this one is the last one, check that the tag form
- * matches the one given in descriptor.
- */
- if(tagno < (td->tags_count - 1)) {
- if(tlv_constr == 0) {
- ASN_DEBUG("tlv_constr = %d, expfail",
- tlv_constr);
- RETURN(RC_FAIL);
- }
- } else {
- if(last_tag_form != tlv_constr
- && last_tag_form != -1) {
- ASN_DEBUG("last_tag_form %d != %d",
- last_tag_form, tlv_constr);
- RETURN(RC_FAIL);
- }
- }
-
- /*
- * Fetch and process L from TLV.
- */
- len_len = ber_fetch_length(tlv_constr,
- (const char *)ptr + tag_len, size - tag_len, &tlv_len);
- ASN_DEBUG("Fetchinig len = %ld", (long)len_len);
- switch(len_len) {
- case -1: RETURN(RC_FAIL);
- case 0: RETURN(RC_WMORE);
- }
-
- /*
- * FIXME
- * As of today, the chain of tags
- * must either contain several indefinite length TLVs,
- * or several definite length ones.
- * No mixing is allowed.
- */
- if(tlv_len == -1) {
- /*
- * Indefinite length.
- */
- if(limit_len == -1) {
- expect_00_terminators++;
- } else {
- ASN_DEBUG("Unexpected indefinite length "
- "in a chain of definite lengths");
- RETURN(RC_FAIL);
- }
- ADVANCE(tag_len + len_len);
- continue;
- } else {
- if(expect_00_terminators) {
- ASN_DEBUG("Unexpected definite length "
- "in a chain of indefinite lengths");
- RETURN(RC_FAIL);
- }
- }
-
- /*
- * Check that multiple TLVs specify ever decreasing length,
- * which is consistent.
- */
- if(limit_len == -1) {
- limit_len = tlv_len + tag_len + len_len;
- if(limit_len < 0) {
- /* Too great tlv_len value? */
- RETURN(RC_FAIL);
- }
- } else if(limit_len != tlv_len + tag_len + len_len) {
- /*
- * Inner TLV specifies length which is inconsistent
- * with the outer TLV's length value.
- */
- ASN_DEBUG("Outer TLV is %ld and inner is %ld",
- (long)limit_len, (long)tlv_len);
- RETURN(RC_FAIL);
- }
-
- ADVANCE(tag_len + len_len);
-
- limit_len -= (tag_len + len_len);
- if((ssize_t)size > limit_len) {
- /*
- * Make sure that we won't consume more bytes
- * from the parent frame than the inferred limit.
- */
- size = limit_len;
- }
- }
-
- if(opt_tlv_form)
- *opt_tlv_form = tlv_constr;
- if(expect_00_terminators)
- *last_length = -expect_00_terminators;
- else
- *last_length = tlv_len;
-
- RETURN(RC_OK);
-}
+++ /dev/null
-/*-
- * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-#ifndef _BER_DECODER_H_
-#define _BER_DECODER_H_
-
-#include <asn_application.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct asn_TYPE_descriptor_s; /* Forward declaration */
-struct asn_codec_ctx_s; /* Forward declaration */
-
-/*
- * The BER decoder of any type.
- * This function may be invoked directly from the application.
- */
-asn_dec_rval_t ber_decode(struct asn_codec_ctx_s *opt_codec_ctx,
- struct asn_TYPE_descriptor_s *type_descriptor,
- void **struct_ptr, /* Pointer to a target structure's pointer */
- const void *buffer, /* Data to be decoded */
- size_t size /* Size of that buffer */
- );
-
-/*
- * Type of generic function which decodes the byte stream into the structure.
- */
-typedef asn_dec_rval_t (ber_type_decoder_f)(
- struct asn_codec_ctx_s *opt_codec_ctx,
- struct asn_TYPE_descriptor_s *type_descriptor,
- void **struct_ptr, const void *buf_ptr, size_t size,
- int tag_mode);
-
-/*******************************
- * INTERNALLY USEFUL FUNCTIONS *
- *******************************/
-
-/*
- * Check that all tags correspond to the type definition (as given in head).
- * On return, last_length would contain either a non-negative length of the
- * value part of the last TLV, or the negative number of expected
- * "end of content" sequences. The number may only be negative if the
- * head->last_tag_form is non-zero.
- */
-asn_dec_rval_t ber_check_tags(
- struct asn_codec_ctx_s *opt_codec_ctx, /* codec options */
- struct asn_TYPE_descriptor_s *type_descriptor,
- asn_struct_ctx_t *opt_ctx, /* saved decoding context */
- const void *ptr, size_t size,
- int tag_mode, /* {-1,0,1}: IMPLICIT, no, EXPLICIT */
- int last_tag_form, /* {-1,0:1}: any, primitive, constr */
- ber_tlv_len_t *last_length,
- int *opt_tlv_form /* optional tag form */
- );
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _BER_DECODER_H_ */
+++ /dev/null
-/*-
- * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-#include <asn_internal.h>
-#include <ber_tlv_length.h>
-#include <ber_tlv_tag.h>
-
-ssize_t
-ber_fetch_length(int _is_constructed, const void *bufptr, size_t size,
- ber_tlv_len_t *len_r) {
- const uint8_t *buf = (const uint8_t *)bufptr;
- unsigned oct;
-
- if(size == 0)
- return 0; /* Want more */
-
- oct = *(const uint8_t *)buf;
- if((oct & 0x80) == 0) {
- /*
- * Short definite length.
- */
- *len_r = oct; /* & 0x7F */
- return 1;
- } else {
- ber_tlv_len_t len;
- size_t skipped;
-
- if(_is_constructed && oct == 0x80) {
- *len_r = -1; /* Indefinite length */
- return 1;
- }
-
- if(oct == 0xff) {
- /* Reserved in standard for future use. */
- return -1;
- }
-
- oct &= 0x7F; /* Leave only the 7 LS bits */
- for(len = 0, buf++, skipped = 1;
- oct && (++skipped <= size); buf++, oct--) {
-
- len = (len << 8) | *buf;
- if(len < 0
- || (len >> ((8 * sizeof(len)) - 8) && oct > 1)) {
- /*
- * Too large length value.
- */
- return -1;
- }
- }
-
- if(oct == 0) {
- ber_tlv_len_t lenplusepsilon = (size_t)len + 1024;
- /*
- * Here length may be very close or equal to 2G.
- * However, the arithmetics used in some decoders
- * may add some (small) quantities to the length,
- * to check the resulting value against some limits.
- * This may result in integer wrap-around, which
- * we try to avoid by checking it earlier here.
- */
- if(lenplusepsilon < 0) {
- /* Too large length value */
- return -1;
- }
-
- *len_r = len;
- return skipped;
- }
-
- return 0; /* Want more */
- }
-
-}
-
-ssize_t
-ber_skip_length(asn_codec_ctx_t *opt_codec_ctx,
- int _is_constructed, const void *ptr, size_t size) {
- ber_tlv_len_t vlen; /* Length of V in TLV */
- ssize_t tl; /* Length of L in TLV */
- ssize_t ll; /* Length of L in TLV */
- size_t skip;
-
- /*
- * Make sure we didn't exceed the maximum stack size.
- */
- if(_ASN_STACK_OVERFLOW_CHECK(opt_codec_ctx))
- return -1;
-
- /*
- * Determine the size of L in TLV.
- */
- ll = ber_fetch_length(_is_constructed, ptr, size, &vlen);
- if(ll <= 0) return ll;
-
- /*
- * Definite length.
- */
- if(vlen >= 0) {
- skip = ll + vlen;
- if(skip > size)
- return 0; /* Want more */
- return skip;
- }
-
- /*
- * Indefinite length!
- */
- ASN_DEBUG("Skipping indefinite length");
- for(skip = ll, ptr = ((const char *)ptr) + ll, size -= ll;;) {
- ber_tlv_tag_t tag;
-
- /* Fetch the tag */
- tl = ber_fetch_tag(ptr, size, &tag);
- if(tl <= 0) return tl;
-
- ll = ber_skip_length(opt_codec_ctx,
- BER_TLV_CONSTRUCTED(ptr),
- ((const char *)ptr) + tl, size - tl);
- if(ll <= 0) return ll;
-
- skip += tl + ll;
-
- /*
- * This may be the end of the indefinite length structure,
- * two consecutive 0 octets.
- * Check if it is true.
- */
- if(((const uint8_t *)ptr)[0] == 0
- && ((const uint8_t *)ptr)[1] == 0)
- return skip;
-
- ptr = ((const char *)ptr) + tl + ll;
- size -= tl + ll;
- }
-
- /* UNREACHABLE */
-}
-
-size_t
-der_tlv_length_serialize(ber_tlv_len_t len, void *bufp, size_t size) {
- size_t required_size; /* Size of len encoding */
- uint8_t *buf = (uint8_t *)bufp;
- uint8_t *end;
- size_t i;
-
- if(len <= 127) {
- /* Encoded in 1 octet */
- if(size) *buf = (uint8_t)len;
- return 1;
- }
-
- /*
- * Compute the size of the subsequent bytes.
- */
- for(required_size = 1, i = 8; i < 8 * sizeof(len); i += 8) {
- if(len >> i)
- required_size++;
- else
- break;
- }
-
- if(size <= required_size)
- return required_size + 1;
-
- *buf++ = (uint8_t)(0x80 | required_size); /* Length of the encoding */
-
- /*
- * Produce the len encoding, space permitting.
- */
- end = buf + required_size;
- for(i -= 8; buf < end; i -= 8, buf++)
- *buf = (uint8_t)(len >> i);
-
- return required_size + 1;
-}
-
+++ /dev/null
-/*-
- * Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-#ifndef _BER_TLV_LENGTH_H_
-#define _BER_TLV_LENGTH_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef ssize_t ber_tlv_len_t;
-
-/*
- * This function tries to fetch the length of the BER TLV value and place it
- * in *len_r.
- * RETURN VALUES:
- * 0: More data expected than bufptr contains.
- * -1: Fatal error deciphering length.
- * >0: Number of bytes used from bufptr.
- * On return with >0, len_r is constrained as -1..MAX, where -1 mean
- * that the value is of indefinite length.
- */
-ssize_t ber_fetch_length(int _is_constructed, const void *bufptr, size_t size,
- ber_tlv_len_t *len_r);
-
-/*
- * This function expects bufptr to be positioned over L in TLV.
- * It returns number of bytes occupied by L and V together, suitable
- * for skipping. The function properly handles indefinite length.
- * RETURN VALUES:
- * Standard {-1,0,>0} convention.
- */
-ssize_t ber_skip_length(
- struct asn_codec_ctx_s *opt_codec_ctx, /* optional context */
- int _is_constructed, const void *bufptr, size_t size);
-
-/*
- * This function serializes the length (L from TLV) in DER format.
- * It always returns number of bytes necessary to represent the length,
- * it is a caller's responsibility to check the return value
- * against the supplied buffer's size.
- */
-size_t der_tlv_length_serialize(ber_tlv_len_t len, void *bufptr, size_t size);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _BER_TLV_LENGTH_H_ */
+++ /dev/null
-/*-
- * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-#include <asn_internal.h>
-#include <ber_tlv_tag.h>
-#include <errno.h>
-
-ssize_t
-ber_fetch_tag(const void *ptr, size_t size, ber_tlv_tag_t *tag_r) {
- ber_tlv_tag_t val;
- ber_tlv_tag_t tclass;
- size_t skipped;
-
- if(size == 0)
- return 0;
-
- val = *(const uint8_t *)ptr;
- tclass = (val >> 6);
- if((val &= 0x1F) != 0x1F) {
- /*
- * Simple form: everything encoded in a single octet.
- * Tag Class is encoded using two least significant bits.
- */
- *tag_r = (val << 2) | tclass;
- return 1;
- }
-
- /*
- * Each octet contains 7 bits of useful information.
- * The MSB is 0 if it is the last octet of the tag.
- */
- for(val = 0, ptr = ((const char *)ptr) + 1, skipped = 2;
- skipped <= size;
- ptr = ((const char *)ptr) + 1, skipped++) {
- unsigned int oct = *(const uint8_t *)ptr;
- if(oct & 0x80) {
- val = (val << 7) | (oct & 0x7F);
- /*
- * Make sure there are at least 9 bits spare
- * at the MS side of a value.
- */
- if(val >> ((8 * sizeof(val)) - 9)) {
- /*
- * We would not be able to accomodate
- * any more tag bits.
- */
- return -1;
- }
- } else {
- val = (val << 7) | oct;
- *tag_r = (val << 2) | tclass;
- return skipped;
- }
- }
-
- return 0; /* Want more */
-}
-
-
-ssize_t
-ber_tlv_tag_fwrite(ber_tlv_tag_t tag, FILE *f) {
- char buf[sizeof("[APPLICATION ]") + 32];
- ssize_t ret;
-
- ret = ber_tlv_tag_snprint(tag, buf, sizeof(buf));
- if(ret >= (ssize_t)sizeof(buf) || ret < 2) {
- errno = EPERM;
- return -1;
- }
-
- return fwrite(buf, 1, ret, f);
-}
-
-ssize_t
-ber_tlv_tag_snprint(ber_tlv_tag_t tag, char *buf, size_t size) {
- char *type = 0;
- int ret;
-
- switch(tag & 0x3) {
- case ASN_TAG_CLASS_UNIVERSAL: type = "UNIVERSAL "; break;
- case ASN_TAG_CLASS_APPLICATION: type = "APPLICATION "; break;
- case ASN_TAG_CLASS_CONTEXT: type = ""; break;
- case ASN_TAG_CLASS_PRIVATE: type = "PRIVATE "; break;
- }
-
- ret = snprintf(buf, size, "[%s%u]", type, ((unsigned)tag) >> 2);
- if(ret <= 0 && size) buf[0] = '\0'; /* against broken libc's */
-
- return ret;
-}
-
-char *
-ber_tlv_tag_string(ber_tlv_tag_t tag) {
- static char buf[sizeof("[APPLICATION ]") + 32];
-
- (void)ber_tlv_tag_snprint(tag, buf, sizeof(buf));
-
- return buf;
-}
-
-
-size_t
-ber_tlv_tag_serialize(ber_tlv_tag_t tag, void *bufp, size_t size) {
- int tclass = BER_TAG_CLASS(tag);
- ber_tlv_tag_t tval = BER_TAG_VALUE(tag);
- uint8_t *buf = (uint8_t *)bufp;
- uint8_t *end;
- size_t required_size;
- size_t i;
-
- if(tval <= 30) {
- /* Encoded in 1 octet */
- if(size) buf[0] = (tclass << 6) | tval;
- return 1;
- } else if(size) {
- *buf++ = (tclass << 6) | 0x1F;
- size--;
- }
-
- /*
- * Compute the size of the subsequent bytes.
- */
- for(required_size = 1, i = 7; i < 8 * sizeof(tval); i += 7) {
- if(tval >> i)
- required_size++;
- else
- break;
- }
-
- if(size < required_size)
- return required_size + 1;
-
- /*
- * Fill in the buffer, space permitting.
- */
- end = buf + required_size - 1;
- for(i -= 7; buf < end; i -= 7, buf++)
- *buf = 0x80 | ((tval >> i) & 0x7F);
- *buf = (tval & 0x7F); /* Last octet without high bit */
-
- return required_size + 1;
-}
-
+++ /dev/null
-/*-
- * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-#ifndef _BER_TLV_TAG_H_
-#define _BER_TLV_TAG_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-enum asn_tag_class {
- ASN_TAG_CLASS_UNIVERSAL = 0, /* 0b00 */
- ASN_TAG_CLASS_APPLICATION = 1, /* 0b01 */
- ASN_TAG_CLASS_CONTEXT = 2, /* 0b10 */
- ASN_TAG_CLASS_PRIVATE = 3 /* 0b11 */
-};
-typedef unsigned ber_tlv_tag_t; /* BER TAG from Tag-Length-Value */
-
-/*
- * Tag class is encoded together with tag value for optimization purposes.
- */
-#define BER_TAG_CLASS(tag) ((tag) & 0x3)
-#define BER_TAG_VALUE(tag) ((tag) >> 2)
-#define BER_TLV_CONSTRUCTED(tagptr) (((*(const uint8_t *)tagptr)&0x20)?1:0)
-
-#define BER_TAGS_EQUAL(tag1, tag2) ((tag1) == (tag2))
-
-/*
- * Several functions for printing the TAG in the canonical form
- * (i.e. "[PRIVATE 0]").
- * Return values correspond to their libc counterparts (if any).
- */
-ssize_t ber_tlv_tag_snprint(ber_tlv_tag_t tag, char *buf, size_t buflen);
-ssize_t ber_tlv_tag_fwrite(ber_tlv_tag_t tag, FILE *);
-char *ber_tlv_tag_string(ber_tlv_tag_t tag);
-
-
-/*
- * This function tries to fetch the tag from the input stream.
- * RETURN VALUES:
- * 0: More data expected than bufptr contains.
- * -1: Fatal error deciphering tag.
- * >0: Number of bytes used from bufptr. tag_r will contain the tag.
- */
-ssize_t ber_fetch_tag(const void *bufptr, size_t size, ber_tlv_tag_t *tag_r);
-
-/*
- * This function serializes the tag (T from TLV) in BER format.
- * It always returns number of bytes necessary to represent the tag,
- * it is a caller's responsibility to check the return value
- * against the supplied buffer's size.
- */
-size_t ber_tlv_tag_serialize(ber_tlv_tag_t tag, void *bufptr, size_t size);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _BER_TLV_TAG_H_ */
+++ /dev/null
-/*
- * Copyright (c) 2003, 2004, 2005, 2006 Lev Walkin <vlm@lionet.info>.
- * All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-#include <asn_internal.h>
-#include <constr_CHOICE.h>
-
-/*
- * Number of bytes left for this structure.
- * (ctx->left) indicates the number of bytes _transferred_ for the structure.
- * (size) contains the number of bytes in the buffer passed.
- */
-#define LEFT ((size<(size_t)ctx->left)?size:(size_t)ctx->left)
-
-/*
- * If the subprocessor function returns with an indication that it wants
- * more data, it may well be a fatal decoding problem, because the
- * size is constrained by the <TLV>'s L, even if the buffer size allows
- * reading more data.
- * For example, consider the buffer containing the following TLVs:
- * <T:5><L:1><V> <T:6>...
- * The TLV length clearly indicates that one byte is expected in V, but
- * if the V processor returns with "want more data" even if the buffer
- * contains way more data than the V processor have seen.
- */
-#define SIZE_VIOLATION (ctx->left >= 0 && (size_t)ctx->left <= size)
-
-/*
- * This macro "eats" the part of the buffer which is definitely "consumed",
- * i.e. was correctly converted into local representation or rightfully skipped.
- */
-#undef ADVANCE
-#define ADVANCE(num_bytes) do { \
- size_t num = num_bytes; \
- ptr = ((const char *)ptr) + num;\
- size -= num; \
- if(ctx->left >= 0) \
- ctx->left -= num; \
- consumed_myself += num; \
- } while(0)
-
-/*
- * Switch to the next phase of parsing.
- */
-#undef NEXT_PHASE
-#define NEXT_PHASE(ctx) do { \
- ctx->phase++; \
- ctx->step = 0; \
- } while(0)
-
-/*
- * Return a standardized complex structure.
- */
-#undef RETURN
-#define RETURN(_code) do { \
- rval.code = _code; \
- rval.consumed = consumed_myself;\
- return rval; \
- } while(0)
-
-/*
- * See the definitions.
- */
-static int _fetch_present_idx(const void *struct_ptr, int off, int size);
-static void _set_present_idx(void *sptr, int offset, int size, int pres);
-
-/*
- * Tags are canonically sorted in the tag to member table.
- */
-static int
-_search4tag(const void *ap, const void *bp) {
- const asn_TYPE_tag2member_t *a = (const asn_TYPE_tag2member_t *)ap;
- const asn_TYPE_tag2member_t *b = (const asn_TYPE_tag2member_t *)bp;
-
- int a_class = BER_TAG_CLASS(a->el_tag);
- int b_class = BER_TAG_CLASS(b->el_tag);
-
- if(a_class == b_class) {
- ber_tlv_tag_t a_value = BER_TAG_VALUE(a->el_tag);
- ber_tlv_tag_t b_value = BER_TAG_VALUE(b->el_tag);
-
- if(a_value == b_value)
- return 0;
- else if(a_value < b_value)
- return -1;
- else
- return 1;
- } else if(a_class < b_class) {
- return -1;
- } else {
- return 1;
- }
-}
-
-/*
- * The decoder of the CHOICE type.
- */
-asn_dec_rval_t
-CHOICE_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
- void **struct_ptr, const void *ptr, size_t size, int tag_mode) {
- /*
- * Bring closer parts of structure description.
- */
- asn_CHOICE_specifics_t *specs = (asn_CHOICE_specifics_t *)td->specifics;
- asn_TYPE_member_t *elements = td->elements;
-
- /*
- * Parts of the structure being constructed.
- */
- void *st = *struct_ptr; /* Target structure. */
- asn_struct_ctx_t *ctx; /* Decoder context */
-
- ber_tlv_tag_t tlv_tag; /* T from TLV */
- ssize_t tag_len; /* Length of TLV's T */
- asn_dec_rval_t rval; /* Return code from subparsers */
-
- ssize_t consumed_myself = 0; /* Consumed bytes from ptr */
-
- ASN_DEBUG("Decoding %s as CHOICE", td->name);
-
- /*
- * Create the target structure if it is not present already.
- */
- if(st == 0) {
- st = *struct_ptr = CALLOC(1, specs->struct_size);
- if(st == 0) {
- RETURN(RC_FAIL);
- }
- }
-
- /*
- * Restore parsing context.
- */
- ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset);
-
- /*
- * Start to parse where left previously
- */
- switch(ctx->phase) {
- case 0:
- /*
- * PHASE 0.
- * Check that the set of tags associated with given structure
- * perfectly fits our expectations.
- */
-
- if(tag_mode || td->tags_count) {
- rval = ber_check_tags(opt_codec_ctx, td, ctx, ptr, size,
- tag_mode, -1, &ctx->left, 0);
- if(rval.code != RC_OK) {
- ASN_DEBUG("%s tagging check failed: %d",
- td->name, rval.code);
- return rval;
- }
-
- if(ctx->left >= 0) {
- /* ?Substracted below! */
- ctx->left += rval.consumed;
- }
- ADVANCE(rval.consumed);
- } else {
- ctx->left = -1;
- }
-
- NEXT_PHASE(ctx);
-
- ASN_DEBUG("Structure consumes %ld bytes, buffer %ld",
- (long)ctx->left, (long)size);
-
- /* Fall through */
- case 1:
- /*
- * Fetch the T from TLV.
- */
- tag_len = ber_fetch_tag(ptr, LEFT, &tlv_tag);
- ASN_DEBUG("In %s CHOICE tag length %d", td->name, (int)tag_len);
- switch(tag_len) {
- case 0: if(!SIZE_VIOLATION) RETURN(RC_WMORE);
- /* Fall through */
- case -1: RETURN(RC_FAIL);
- }
-
- do {
- asn_TYPE_tag2member_t *t2m;
- asn_TYPE_tag2member_t key;
-
- key.el_tag = tlv_tag;
- t2m = (asn_TYPE_tag2member_t *)bsearch(&key,
- specs->tag2el, specs->tag2el_count,
- sizeof(specs->tag2el[0]), _search4tag);
- if(t2m) {
- /*
- * Found the element corresponding to the tag.
- */
- NEXT_PHASE(ctx);
- ctx->step = t2m->el_no;
- break;
- } else if(specs->ext_start == -1) {
- ASN_DEBUG("Unexpected tag %s "
- "in non-extensible CHOICE %s",
- ber_tlv_tag_string(tlv_tag), td->name);
- RETURN(RC_FAIL);
- } else {
- /* Skip this tag */
- ssize_t skip;
-
- ASN_DEBUG("Skipping unknown tag %s",
- ber_tlv_tag_string(tlv_tag));
-
- skip = ber_skip_length(opt_codec_ctx,
- BER_TLV_CONSTRUCTED(ptr),
- (const char *)ptr + tag_len,
- LEFT - tag_len);
-
- switch(skip) {
- case 0: if(!SIZE_VIOLATION) RETURN(RC_WMORE);
- /* Fall through */
- case -1: RETURN(RC_FAIL);
- }
-
- ADVANCE(skip + tag_len);
- RETURN(RC_OK);
- }
- } while(0);
-
- case 2:
- /*
- * PHASE 2.
- * Read in the element.
- */
- do {
- asn_TYPE_member_t *elm;/* CHOICE's element */
- void *memb_ptr; /* Pointer to the member */
- void **memb_ptr2; /* Pointer to that pointer */
-
- elm = &elements[ctx->step];
-
- /*
- * Compute the position of the member inside a structure,
- * and also a type of containment (it may be contained
- * as pointer or using inline inclusion).
- */
- if(elm->flags & ATF_POINTER) {
- /* Member is a pointer to another structure */
- memb_ptr2 = (void **)((char *)st + elm->memb_offset);
- } else {
- /*
- * A pointer to a pointer
- * holding the start of the structure
- */
- memb_ptr = (char *)st + elm->memb_offset;
- memb_ptr2 = &memb_ptr;
- }
- /* Set presence to be able to free it properly at any time */
- _set_present_idx(st, specs->pres_offset,
- specs->pres_size, ctx->step + 1);
- /*
- * Invoke the member fetch routine according to member's type
- */
- rval = elm->type->ber_decoder(opt_codec_ctx, elm->type,
- memb_ptr2, ptr, LEFT, elm->tag_mode);
- switch(rval.code) {
- case RC_OK:
- break;
- case RC_WMORE: /* More data expected */
- if(!SIZE_VIOLATION) {
- ADVANCE(rval.consumed);
- RETURN(RC_WMORE);
- }
- RETURN(RC_FAIL);
- case RC_FAIL: /* Fatal error */
- RETURN(rval.code);
- } /* switch(rval) */
-
- ADVANCE(rval.consumed);
- } while(0);
-
- NEXT_PHASE(ctx);
-
- /* Fall through */
- case 3:
- ASN_DEBUG("CHOICE %s Leftover: %ld, size = %ld, tm=%d, tc=%d",
- td->name, (long)ctx->left, (long)size,
- tag_mode, td->tags_count);
-
- if(ctx->left > 0) {
- /*
- * The type must be fully decoded
- * by the CHOICE member-specific decoder.
- */
- RETURN(RC_FAIL);
- }
-
- if(ctx->left == -1
- && !(tag_mode || td->tags_count)) {
- /*
- * This is an untagged CHOICE.
- * It doesn't contain nothing
- * except for the member itself, including all its tags.
- * The decoding is completed.
- */
- NEXT_PHASE(ctx);
- break;
- }
-
- /*
- * Read in the "end of data chunks"'s.
- */
- while(ctx->left < 0) {
- ssize_t tl;
-
- tl = ber_fetch_tag(ptr, LEFT, &tlv_tag);
- switch(tl) {
- case 0: if(!SIZE_VIOLATION) RETURN(RC_WMORE);
- /* Fall through */
- case -1: RETURN(RC_FAIL);
- }
-
- /*
- * Expected <0><0>...
- */
- if(((const uint8_t *)ptr)[0] == 0) {
- if(LEFT < 2) {
- if(SIZE_VIOLATION)
- RETURN(RC_FAIL);
- else
- RETURN(RC_WMORE);
- } else if(((const uint8_t *)ptr)[1] == 0) {
- /*
- * Correctly finished with <0><0>.
- */
- ADVANCE(2);
- ctx->left++;
- continue;
- }
- } else {
- ASN_DEBUG("Unexpected continuation in %s",
- td->name);
- RETURN(RC_FAIL);
- }
-
- /* UNREACHABLE */
- }
-
- NEXT_PHASE(ctx);
- case 4:
- /* No meaningful work here */
- break;
- }
-
- RETURN(RC_OK);
-}
-
-asn_enc_rval_t
-CHOICE_encode_der(asn_TYPE_descriptor_t *td, void *sptr,
- int tag_mode, ber_tlv_tag_t tag,
- asn_app_consume_bytes_f *cb, void *app_key) {
- asn_CHOICE_specifics_t *specs = (asn_CHOICE_specifics_t *)td->specifics;
- asn_TYPE_member_t *elm; /* CHOICE element */
- asn_enc_rval_t erval;
- void *memb_ptr;
- size_t computed_size = 0;
- int present;
-
- if(!sptr) _ASN_ENCODE_FAILED;
-
- ASN_DEBUG("%s %s as CHOICE",
- cb?"Encoding":"Estimating", td->name);
-
- present = _fetch_present_idx(sptr,
- specs->pres_offset, specs->pres_size);
-
- /*
- * If the structure was not initialized, it cannot be encoded:
- * can't deduce what to encode in the choice type.
- */
- if(present <= 0 || present > td->elements_count) {
- if(present == 0 && td->elements_count == 0) {
- /* The CHOICE is empty?! */
- erval.encoded = 0;
- _ASN_ENCODED_OK(erval);
- }
- _ASN_ENCODE_FAILED;
- }
-
- /*
- * Seek over the present member of the structure.
- */
- elm = &td->elements[present-1];
- if(elm->flags & ATF_POINTER) {
- memb_ptr = *(void **)((char *)sptr + elm->memb_offset);
- if(memb_ptr == 0) {
- if(elm->optional) {
- erval.encoded = 0;
- _ASN_ENCODED_OK(erval);
- }
- /* Mandatory element absent */
- _ASN_ENCODE_FAILED;
- }
- } else {
- memb_ptr = (void *)((char *)sptr + elm->memb_offset);
- }
-
- /*
- * If the CHOICE itself is tagged EXPLICIT:
- * T ::= [2] EXPLICIT CHOICE { ... }
- * Then emit the appropriate tags.
- */
- if(tag_mode == 1 || td->tags_count) {
- /*
- * For this, we need to pre-compute the member.
- */
- ssize_t ret;
-
- /* Encode member with its tag */
- erval = elm->type->der_encoder(elm->type, memb_ptr,
- elm->tag_mode, elm->tag, 0, 0);
- if(erval.encoded == -1)
- return erval;
-
- /* Encode CHOICE with parent or my own tag */
- ret = der_write_tags(td, erval.encoded, tag_mode, 1, tag,
- cb, app_key);
- if(ret == -1)
- _ASN_ENCODE_FAILED;
- computed_size += ret;
- }
-
- /*
- * Encode the single underlying member.
- */
- erval = elm->type->der_encoder(elm->type, memb_ptr,
- elm->tag_mode, elm->tag, cb, app_key);
- if(erval.encoded == -1)
- return erval;
-
- ASN_DEBUG("Encoded CHOICE member in %ld bytes (+%ld)",
- (long)erval.encoded, (long)computed_size);
-
- erval.encoded += computed_size;
-
- return erval;
-}
-
-ber_tlv_tag_t
-CHOICE_outmost_tag(asn_TYPE_descriptor_t *td, const void *ptr, int tag_mode, ber_tlv_tag_t tag) {
- asn_CHOICE_specifics_t *specs = (asn_CHOICE_specifics_t *)td->specifics;
- int present;
-
- assert(tag_mode == 0); (void)tag_mode;
- assert(tag == 0); (void)tag;
-
- /*
- * Figure out which CHOICE element is encoded.
- */
- present = _fetch_present_idx(ptr, specs->pres_offset, specs->pres_size);
-
- if(present > 0 || present <= td->elements_count) {
- asn_TYPE_member_t *elm = &td->elements[present-1];
- const void *memb_ptr;
-
- if(elm->flags & ATF_POINTER) {
- memb_ptr = *(const void * const *)
- ((const char *)ptr + elm->memb_offset);
- } else {
- memb_ptr = (const void *)
- ((const char *)ptr + elm->memb_offset);
- }
-
- return asn_TYPE_outmost_tag(elm->type, memb_ptr,
- elm->tag_mode, elm->tag);
- } else {
- return (ber_tlv_tag_t)-1;
- }
-}
-
-int
-CHOICE_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
- asn_app_constraint_failed_f *ctfailcb, void *app_key) {
- asn_CHOICE_specifics_t *specs = (asn_CHOICE_specifics_t *)td->specifics;
- int present;
-
- if(!sptr) {
- _ASN_CTFAIL(app_key, td,
- "%s: value not given (%s:%d)",
- td->name, __FILE__, __LINE__);
- return -1;
- }
-
- /*
- * Figure out which CHOICE element is encoded.
- */
- present = _fetch_present_idx(sptr, specs->pres_offset,specs->pres_size);
- if(present > 0 && present <= td->elements_count) {
- asn_TYPE_member_t *elm = &td->elements[present-1];
- const void *memb_ptr;
-
- if(elm->flags & ATF_POINTER) {
- memb_ptr = *(const void * const *)((const char *)sptr + elm->memb_offset);
- if(!memb_ptr) {
- if(elm->optional)
- return 0;
- _ASN_CTFAIL(app_key, td,
- "%s: mandatory CHOICE element %s absent (%s:%d)",
- td->name, elm->name, __FILE__, __LINE__);
- return -1;
- }
- } else {
- memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
- }
-
- if(elm->memb_constraints) {
- return elm->memb_constraints(elm->type, memb_ptr,
- ctfailcb, app_key);
- } else {
- int ret = elm->type->check_constraints(elm->type,
- memb_ptr, ctfailcb, app_key);
- /*
- * Cannot inherit it eralier:
- * need to make sure we get the updated version.
- */
- elm->memb_constraints = elm->type->check_constraints;
- return ret;
- }
- } else {
- _ASN_CTFAIL(app_key, td,
- "%s: no CHOICE element given (%s:%d)",
- td->name, __FILE__, __LINE__);
- return -1;
- }
-}
-
-#undef XER_ADVANCE
-#define XER_ADVANCE(num_bytes) do { \
- size_t num = num_bytes; \
- buf_ptr = ((const char *)buf_ptr) + num;\
- size -= num; \
- consumed_myself += num; \
- } while(0)
-
-/*
- * Decode the XER (XML) data.
- */
-asn_dec_rval_t
-CHOICE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
- void **struct_ptr, const char *opt_mname,
- const void *buf_ptr, size_t size) {
- /*
- * Bring closer parts of structure description.
- */
- asn_CHOICE_specifics_t *specs = (asn_CHOICE_specifics_t *)td->specifics;
- const char *xml_tag = opt_mname ? opt_mname : td->xml_tag;
-
- /*
- * Parts of the structure being constructed.
- */
- void *st = *struct_ptr; /* Target structure. */
- asn_struct_ctx_t *ctx; /* Decoder context */
-
- asn_dec_rval_t rval; /* Return value of a decoder */
- ssize_t consumed_myself = 0; /* Consumed bytes from ptr */
- int edx; /* Element index */
-
- /*
- * Create the target structure if it is not present already.
- */
- if(st == 0) {
- st = *struct_ptr = CALLOC(1, specs->struct_size);
- if(st == 0) RETURN(RC_FAIL);
- }
-
- /*
- * Restore parsing context.
- */
- ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset);
- if(ctx->phase == 0 && !*xml_tag)
- ctx->phase = 1; /* Skip the outer tag checking phase */
-
- /*
- * Phases of XER/XML processing:
- * Phase 0: Check that the opening tag matches our expectations.
- * Phase 1: Processing body and reacting on closing tag.
- * Phase 2: Processing inner type.
- * Phase 3: Only waiting for closing tag.
- * Phase 4: Skipping unknown extensions.
- * Phase 5: PHASED OUT
- */
- for(edx = ctx->step; ctx->phase <= 4;) {
- pxer_chunk_type_e ch_type; /* XER chunk type */
- ssize_t ch_size; /* Chunk size */
- xer_check_tag_e tcv; /* Tag check value */
- asn_TYPE_member_t *elm;
-
- /*
- * Go inside the member.
- */
- if(ctx->phase == 2) {
- asn_dec_rval_t tmprval;
- void *memb_ptr; /* Pointer to the member */
- void **memb_ptr2; /* Pointer to that pointer */
-
- elm = &td->elements[edx];
-
- if(elm->flags & ATF_POINTER) {
- /* Member is a pointer to another structure */
- memb_ptr2 = (void **)((char *)st
- + elm->memb_offset);
- } else {
- memb_ptr = (char *)st + elm->memb_offset;
- memb_ptr2 = &memb_ptr;
- }
-
- /* Start/Continue decoding the inner member */
- tmprval = elm->type->xer_decoder(opt_codec_ctx,
- elm->type, memb_ptr2, elm->name,
- buf_ptr, size);
- XER_ADVANCE(tmprval.consumed);
- ASN_DEBUG("XER/CHOICE: itdf: [%s] code=%d",
- elm->type->name, tmprval.code);
- if(tmprval.code != RC_OK)
- RETURN(tmprval.code);
- assert(_fetch_present_idx(st,
- specs->pres_offset, specs->pres_size) == 0);
- /* Record what we've got */
- _set_present_idx(st,
- specs->pres_offset, specs->pres_size, edx + 1);
- ctx->phase = 3;
- /* Fall through */
- }
-
- /* No need to wait for closing tag; special mode. */
- if(ctx->phase == 3 && !*xml_tag) {
- ctx->phase = 5; /* Phase out */
- RETURN(RC_OK);
- }
-
- /*
- * Get the next part of the XML stream.
- */
- ch_size = xer_next_token(&ctx->context, buf_ptr, size, &ch_type);
- switch(ch_size) {
- case -1: RETURN(RC_FAIL);
- case 0: RETURN(RC_WMORE);
- default:
- switch(ch_type) {
- case PXER_COMMENT: /* Got XML comment */
- case PXER_TEXT: /* Ignore free-standing text */
- XER_ADVANCE(ch_size); /* Skip silently */
- continue;
- case PXER_TAG:
- break; /* Check the rest down there */
- }
- }
-
- tcv = xer_check_tag(buf_ptr, ch_size, xml_tag);
- ASN_DEBUG("XER/CHOICE checked [%c%c%c%c] vs [%s], tcv=%d",
- ch_size>0?((const uint8_t *)buf_ptr)[0]:'?',
- ch_size>1?((const uint8_t *)buf_ptr)[1]:'?',
- ch_size>2?((const uint8_t *)buf_ptr)[2]:'?',
- ch_size>3?((const uint8_t *)buf_ptr)[3]:'?',
- xml_tag, tcv);
-
- /* Skip the extensions section */
- if(ctx->phase == 4) {
- ASN_DEBUG("skip_unknown(%d, %ld)",
- tcv, (long)ctx->left);
- switch(xer_skip_unknown(tcv, &ctx->left)) {
- case -1:
- ctx->phase = 5;
- RETURN(RC_FAIL);
- continue;
- case 1:
- ctx->phase = 3;
- /* Fall through */
- case 0:
- XER_ADVANCE(ch_size);
- continue;
- case 2:
- ctx->phase = 3;
- break;
- }
- }
-
- switch(tcv) {
- case XCT_BOTH:
- break; /* No CHOICE? */
- case XCT_CLOSING:
- if(ctx->phase != 3)
- break;
- XER_ADVANCE(ch_size);
- ctx->phase = 5; /* Phase out */
- RETURN(RC_OK);
- case XCT_OPENING:
- if(ctx->phase == 0) {
- XER_ADVANCE(ch_size);
- ctx->phase = 1; /* Processing body phase */
- continue;
- }
- /* Fall through */
- case XCT_UNKNOWN_OP:
- case XCT_UNKNOWN_BO:
-
- if(ctx->phase != 1)
- break; /* Really unexpected */
-
- /*
- * Search which inner member corresponds to this tag.
- */
- for(edx = 0; edx < td->elements_count; edx++) {
- elm = &td->elements[edx];
- tcv = xer_check_tag(buf_ptr,ch_size,elm->name);
- switch(tcv) {
- case XCT_BOTH:
- case XCT_OPENING:
- /*
- * Process this member.
- */
- ctx->step = edx;
- ctx->phase = 2;
- break;
- case XCT_UNKNOWN_OP:
- case XCT_UNKNOWN_BO:
- continue;
- default:
- edx = td->elements_count;
- break; /* Phase out */
- }
- break;
- }
- if(edx != td->elements_count)
- continue;
-
- /* It is expected extension */
- if(specs->ext_start != -1) {
- ASN_DEBUG("Got anticipated extension");
- /*
- * Check for (XCT_BOTH or XCT_UNKNOWN_BO)
- * By using a mask. Only record a pure
- * <opening> tags.
- */
- if(tcv & XCT_CLOSING) {
- /* Found </extension> without body */
- ctx->phase = 3; /* Terminating */
- } else {
- ctx->left = 1;
- ctx->phase = 4; /* Skip ...'s */
- }
- XER_ADVANCE(ch_size);
- continue;
- }
-
- /* Fall through */
- default:
- break;
- }
-
- ASN_DEBUG("Unexpected XML tag [%c%c%c%c] in CHOICE [%s]"
- " (ph=%d, tag=%s)",
- ch_size>0?((const uint8_t *)buf_ptr)[0]:'?',
- ch_size>1?((const uint8_t *)buf_ptr)[1]:'?',
- ch_size>2?((const uint8_t *)buf_ptr)[2]:'?',
- ch_size>3?((const uint8_t *)buf_ptr)[3]:'?',
- td->name, ctx->phase, xml_tag);
- break;
- }
-
- ctx->phase = 5; /* Phase out, just in case */
- RETURN(RC_FAIL);
-}
-
-
-asn_enc_rval_t
-CHOICE_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
- int ilevel, enum xer_encoder_flags_e flags,
- asn_app_consume_bytes_f *cb, void *app_key) {
- asn_CHOICE_specifics_t *specs=(asn_CHOICE_specifics_t *)td->specifics;
- asn_enc_rval_t er;
- int present;
-
- if(!sptr)
- _ASN_ENCODE_FAILED;
-
- /*
- * Figure out which CHOICE element is encoded.
- */
- present = _fetch_present_idx(sptr, specs->pres_offset,specs->pres_size);
-
- if(present <= 0 || present > td->elements_count) {
- _ASN_ENCODE_FAILED;
- } else {
- asn_enc_rval_t tmper;
- asn_TYPE_member_t *elm = &td->elements[present-1];
- void *memb_ptr;
- const char *mname = elm->name;
- unsigned int mlen = strlen(mname);
-
- if(elm->flags & ATF_POINTER) {
- memb_ptr = *(void **)((char *)sptr + elm->memb_offset);
- if(!memb_ptr) _ASN_ENCODE_FAILED;
- } else {
- memb_ptr = (void *)((char *)sptr + elm->memb_offset);
- }
-
- er.encoded = 0;
-
- if(!(flags & XER_F_CANONICAL)) _i_ASN_TEXT_INDENT(1, ilevel);
- _ASN_CALLBACK3("<", 1, mname, mlen, ">", 1);
-
- tmper = elm->type->xer_encoder(elm->type, memb_ptr,
- ilevel + 1, flags, cb, app_key);
- if(tmper.encoded == -1) return tmper;
-
- _ASN_CALLBACK3("</", 2, mname, mlen, ">", 1);
-
- er.encoded += 5 + (2 * mlen) + tmper.encoded;
- }
-
- if(!(flags & XER_F_CANONICAL)) _i_ASN_TEXT_INDENT(1, ilevel - 1);
-
- _ASN_ENCODED_OK(er);
-cb_failed:
- _ASN_ENCODE_FAILED;
-}
-
-asn_dec_rval_t
-CHOICE_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
- asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
- asn_CHOICE_specifics_t *specs = (asn_CHOICE_specifics_t *)td->specifics;
- asn_dec_rval_t rv;
- asn_per_constraint_t *ct;
- asn_TYPE_member_t *elm; /* CHOICE's element */
- void *memb_ptr;
- void **memb_ptr2;
- void *st = *sptr;
- int value;
-
- if(_ASN_STACK_OVERFLOW_CHECK(opt_codec_ctx))
- _ASN_DECODE_FAILED;
-
- /*
- * Create the target structure if it is not present already.
- */
- if(!st) {
- st = *sptr = CALLOC(1, specs->struct_size);
- if(!st) _ASN_DECODE_FAILED;
- }
-
- if(constraints) ct = &constraints->value;
- else if(td->per_constraints) ct = &td->per_constraints->value;
- else ct = 0;
-
- if(ct && ct->flags & APC_EXTENSIBLE) {
- value = per_get_few_bits(pd, 1);
- if(value < 0) _ASN_DECODE_STARVED;
- if(value) ct = 0; /* Not restricted */
- }
-
- if(ct && ct->range_bits >= 0) {
- value = per_get_few_bits(pd, ct->range_bits);
- if(value < 0) _ASN_DECODE_STARVED;
- ASN_DEBUG("CHOICE %s got index %d in range %d",
- td->name, value, ct->range_bits);
- if(value > ct->upper_bound)
- _ASN_DECODE_FAILED;
- } else {
- if(specs->ext_start == -1)
- _ASN_DECODE_FAILED;
- value = uper_get_nsnnwn(pd);
- if(value < 0) _ASN_DECODE_STARVED;
- value += specs->ext_start;
- if(value >= td->elements_count)
- _ASN_DECODE_FAILED;
- ASN_DEBUG("NOT IMPLEMENTED YET");
- _ASN_DECODE_FAILED;
- }
-
- /* Adjust if canonical order is different from natural order */
- if(specs->canonical_order)
- value = specs->canonical_order[value];
-
- /* Set presence to be able to free it later */
- _set_present_idx(st, specs->pres_offset, specs->pres_size, value + 1);
-
- elm = &td->elements[value];
- if(elm->flags & ATF_POINTER) {
- /* Member is a pointer to another structure */
- memb_ptr2 = (void **)((char *)st + elm->memb_offset);
- } else {
- memb_ptr = (char *)st + elm->memb_offset;
- memb_ptr2 = &memb_ptr;
- }
- ASN_DEBUG("Discovered CHOICE %s encodes %s", td->name, elm->name);
-
- rv = elm->type->uper_decoder(opt_codec_ctx, elm->type,
- elm->per_constraints, memb_ptr2, pd);
- if(rv.code != RC_OK)
- ASN_DEBUG("Failed to decode %s in %s (CHOICE)",
- elm->name, td->name);
- return rv;
-}
-
-asn_enc_rval_t
-CHOICE_encode_uper(asn_TYPE_descriptor_t *td,
- asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
- asn_CHOICE_specifics_t *specs = (asn_CHOICE_specifics_t *)td->specifics;
- asn_TYPE_member_t *elm; /* CHOICE's element */
- asn_per_constraint_t *ct;
- void *memb_ptr;
- int present;
-
- if(!sptr) _ASN_ENCODE_FAILED;
-
- ASN_DEBUG("Encoding %s as CHOICE", td->name);
-
- if(constraints) ct = &constraints->value;
- else if(td->per_constraints) ct = &td->per_constraints->value;
- else ct = 0;
-
- present = _fetch_present_idx(sptr,
- specs->pres_offset, specs->pres_size);
-
- /*
- * If the structure was not initialized properly, it cannot be encoded:
- * can't deduce what to encode in the choice type.
- */
- if(present <= 0 || present > td->elements_count)
- _ASN_ENCODE_FAILED;
- else
- present--;
-
- /* Adjust if canonical order is different from natural order */
- if(specs->canonical_order)
- present = specs->canonical_order[present];
-
- ASN_DEBUG("Encoding %s CHOICE element %d", td->name, present);
-
- if(ct && ct->range_bits >= 0) {
- if(present < ct->lower_bound
- || present > ct->upper_bound) {
- if(ct->flags & APC_EXTENSIBLE) {
- if(per_put_few_bits(po, 1, 1))
- _ASN_ENCODE_FAILED;
- } else {
- _ASN_ENCODE_FAILED;
- }
- ct = 0;
- }
- }
- if(ct && ct->flags & APC_EXTENSIBLE)
- if(per_put_few_bits(po, 0, 1))
- _ASN_ENCODE_FAILED;
-
- if(ct && ct->range_bits >= 0) {
- if(per_put_few_bits(po, present, ct->range_bits))
- _ASN_ENCODE_FAILED;
- } else {
- if(specs->ext_start == -1)
- _ASN_ENCODE_FAILED;
- if(uper_put_nsnnwn(po, present - specs->ext_start))
- _ASN_ENCODE_FAILED;
- ASN_DEBUG("NOT IMPLEMENTED YET");
- _ASN_ENCODE_FAILED;
- }
-
- elm = &td->elements[present];
- if(elm->flags & ATF_POINTER) {
- /* Member is a pointer to another structure */
- memb_ptr = *(void **)((char *)sptr + elm->memb_offset);
- if(!memb_ptr) _ASN_ENCODE_FAILED;
- } else {
- memb_ptr = (char *)sptr + elm->memb_offset;
- }
-
- return elm->type->uper_encoder(elm->type, elm->per_constraints,
- memb_ptr, po);
-}
-
-
-int
-CHOICE_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
- asn_app_consume_bytes_f *cb, void *app_key) {
- asn_CHOICE_specifics_t *specs = (asn_CHOICE_specifics_t *)td->specifics;
- int present;
-
- if(!sptr) return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
-
- /*
- * Figure out which CHOICE element is encoded.
- */
- present = _fetch_present_idx(sptr, specs->pres_offset,specs->pres_size);
-
- /*
- * Print that element.
- */
- if(present > 0 && present <= td->elements_count) {
- asn_TYPE_member_t *elm = &td->elements[present-1];
- const void *memb_ptr;
-
- if(elm->flags & ATF_POINTER) {
- memb_ptr = *(const void * const *)((const char *)sptr + elm->memb_offset);
- if(!memb_ptr) return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
- } else {
- memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
- }
-
- /* Print member's name and stuff */
- if(0) {
- if(cb(elm->name, strlen(elm->name), app_key) < 0
- || cb(": ", 2, app_key) < 0)
- return -1;
- }
-
- return elm->type->print_struct(elm->type, memb_ptr, ilevel,
- cb, app_key);
- } else {
- return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
- }
-}
-
-void
-CHOICE_free(asn_TYPE_descriptor_t *td, void *ptr, int contents_only) {
- asn_CHOICE_specifics_t *specs = (asn_CHOICE_specifics_t *)td->specifics;
- int present;
-
- if(!td || !ptr)
- return;
-
- ASN_DEBUG("Freeing %s as CHOICE", td->name);
-
- /*
- * Figure out which CHOICE element is encoded.
- */
- present = _fetch_present_idx(ptr, specs->pres_offset, specs->pres_size);
-
- /*
- * Free that element.
- */
- if(present > 0 && present <= td->elements_count) {
- asn_TYPE_member_t *elm = &td->elements[present-1];
- void *memb_ptr;
-
- if(elm->flags & ATF_POINTER) {
- memb_ptr = *(void **)((char *)ptr + elm->memb_offset);
- if(memb_ptr)
- ASN_STRUCT_FREE(*elm->type, memb_ptr);
- } else {
- memb_ptr = (void *)((char *)ptr + elm->memb_offset);
- ASN_STRUCT_FREE_CONTENTS_ONLY(*elm->type, memb_ptr);
- }
- }
-
- if(!contents_only) {
- FREEMEM(ptr);
- }
-}
-
-
-/*
- * The following functions functions offer protection against -fshort-enums,
- * compatible with little- and big-endian machines.
- * If assertion is triggered, either disable -fshort-enums, or add an entry
- * here with the ->pres_size of your target stracture.
- * Unless the target structure is packed, the ".present" member
- * is guaranteed to be aligned properly. ASN.1 compiler itself does not
- * produce packed code.
- */
-static int
-_fetch_present_idx(const void *struct_ptr, int pres_offset, int pres_size) {
- const void *present_ptr;
- int present;
-
- present_ptr = ((const char *)struct_ptr) + pres_offset;
-
- switch(pres_size) {
- case sizeof(int): present = *(const int *)present_ptr; break;
- case sizeof(short): present = *(const short *)present_ptr; break;
- case sizeof(char): present = *(const char *)present_ptr; break;
- default:
- /* ANSI C mandates enum to be equivalent to integer */
- assert(pres_size != sizeof(int));
- return 0; /* If not aborted, pass back safe value */
- }
-
- return present;
-}
-
-static void
-_set_present_idx(void *struct_ptr, int pres_offset, int pres_size, int present) {
- void *present_ptr;
- present_ptr = ((char *)struct_ptr) + pres_offset;
-
- switch(pres_size) {
- case sizeof(int): *(int *)present_ptr = present; break;
- case sizeof(short): *(short *)present_ptr = present; break;
- case sizeof(char): *(char *)present_ptr = present; break;
- default:
- /* ANSI C mandates enum to be equivalent to integer */
- assert(pres_size != sizeof(int));
- }
-}
+++ /dev/null
-/*-
- * Copyright (c) 2003, 2004, 2005 Lev Walkin <vlm@lionet.info>.
- * All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-#ifndef _CONSTR_CHOICE_H_
-#define _CONSTR_CHOICE_H_
-
-#include <asn_application.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct asn_CHOICE_specifics_s {
- /*
- * Target structure description.
- */
- int struct_size; /* Size of the target structure. */
- int ctx_offset; /* Offset of the asn_codec_ctx_t member */
- int pres_offset; /* Identifier of the present member */
- int pres_size; /* Size of the identifier (enum) */
-
- /*
- * Tags to members mapping table.
- */
- asn_TYPE_tag2member_t *tag2el;
- int tag2el_count;
-
- /* Canonical ordering of CHOICE elements, for PER */
- int *canonical_order;
-
- /*
- * Extensions-related stuff.
- */
- int ext_start; /* First member of extensions, or -1 */
-} asn_CHOICE_specifics_t;
-
-/*
- * A set specialized functions dealing with the CHOICE type.
- */
-asn_struct_free_f CHOICE_free;
-asn_struct_print_f CHOICE_print;
-asn_constr_check_f CHOICE_constraint;
-ber_type_decoder_f CHOICE_decode_ber;
-der_type_encoder_f CHOICE_encode_der;
-xer_type_decoder_f CHOICE_decode_xer;
-xer_type_encoder_f CHOICE_encode_xer;
-per_type_decoder_f CHOICE_decode_uper;
-per_type_encoder_f CHOICE_encode_uper;
-asn_outmost_tag_f CHOICE_outmost_tag;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _CONSTR_CHOICE_H_ */
+++ /dev/null
-/*-
- * Copyright (c) 2003, 2004, 2005, 2006 Lev Walkin <vlm@lionet.info>.
- * All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-#include <asn_internal.h>
-#include <constr_SEQUENCE.h>
-
-/*
- * Number of bytes left for this structure.
- * (ctx->left) indicates the number of bytes _transferred_ for the structure.
- * (size) contains the number of bytes in the buffer passed.
- */
-#define LEFT ((size<(size_t)ctx->left)?size:(size_t)ctx->left)
-
-/*
- * If the subprocessor function returns with an indication that it wants
- * more data, it may well be a fatal decoding problem, because the
- * size is constrained by the <TLV>'s L, even if the buffer size allows
- * reading more data.
- * For example, consider the buffer containing the following TLVs:
- * <T:5><L:1><V> <T:6>...
- * The TLV length clearly indicates that one byte is expected in V, but
- * if the V processor returns with "want more data" even if the buffer
- * contains way more data than the V processor have seen.
- */
-#define SIZE_VIOLATION (ctx->left >= 0 && (size_t)ctx->left <= size)
-
-/*
- * This macro "eats" the part of the buffer which is definitely "consumed",
- * i.e. was correctly converted into local representation or rightfully skipped.
- */
-#undef ADVANCE
-#define ADVANCE(num_bytes) do { \
- size_t num = num_bytes; \
- ptr = ((const char *)ptr) + num;\
- size -= num; \
- if(ctx->left >= 0) \
- ctx->left -= num; \
- consumed_myself += num; \
- } while(0)
-
-/*
- * Switch to the next phase of parsing.
- */
-#undef NEXT_PHASE
-#undef PHASE_OUT
-#define NEXT_PHASE(ctx) do { \
- ctx->phase++; \
- ctx->step = 0; \
- } while(0)
-#define PHASE_OUT(ctx) do { ctx->phase = 10; } while(0)
-
-/*
- * Return a standardized complex structure.
- */
-#undef RETURN
-#define RETURN(_code) do { \
- rval.code = _code; \
- rval.consumed = consumed_myself;\
- return rval; \
- } while(0)
-
-/*
- * Check whether we are inside the extensions group.
- */
-#define IN_EXTENSION_GROUP(specs, memb_idx) \
- ( ((memb_idx) > (specs)->ext_after) \
- &&((memb_idx) < (specs)->ext_before))
-
-
-/*
- * Tags are canonically sorted in the tag2element map.
- */
-static int
-_t2e_cmp(const void *ap, const void *bp) {
- const asn_TYPE_tag2member_t *a = (const asn_TYPE_tag2member_t *)ap;
- const asn_TYPE_tag2member_t *b = (const asn_TYPE_tag2member_t *)bp;
-
- int a_class = BER_TAG_CLASS(a->el_tag);
- int b_class = BER_TAG_CLASS(b->el_tag);
-
- if(a_class == b_class) {
- ber_tlv_tag_t a_value = BER_TAG_VALUE(a->el_tag);
- ber_tlv_tag_t b_value = BER_TAG_VALUE(b->el_tag);
-
- if(a_value == b_value) {
- if(a->el_no > b->el_no)
- return 1;
- /*
- * Important: we do not check
- * for a->el_no <= b->el_no!
- */
- return 0;
- } else if(a_value < b_value)
- return -1;
- else
- return 1;
- } else if(a_class < b_class) {
- return -1;
- } else {
- return 1;
- }
-}
-
-
-/*
- * The decoder of the SEQUENCE type.
- */
-asn_dec_rval_t
-SEQUENCE_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
- void **struct_ptr, const void *ptr, size_t size, int tag_mode) {
- /*
- * Bring closer parts of structure description.
- */
- asn_SEQUENCE_specifics_t *specs = (asn_SEQUENCE_specifics_t *)td->specifics;
- asn_TYPE_member_t *elements = td->elements;
-
- /*
- * Parts of the structure being constructed.
- */
- void *st = *struct_ptr; /* Target structure. */
- asn_struct_ctx_t *ctx; /* Decoder context */
-
- ber_tlv_tag_t tlv_tag; /* T from TLV */
- asn_dec_rval_t rval; /* Return code from subparsers */
-
- ssize_t consumed_myself = 0; /* Consumed bytes from ptr */
- int edx; /* SEQUENCE element's index */
-
- ASN_DEBUG("Decoding %s as SEQUENCE", td->name);
-
- /*
- * Create the target structure if it is not present already.
- */
- if(st == 0) {
- st = *struct_ptr = CALLOC(1, specs->struct_size);
- if(st == 0) {
- RETURN(RC_FAIL);
- }
- }
-
- /*
- * Restore parsing context.
- */
- ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset);
-
- /*
- * Start to parse where left previously
- */
- switch(ctx->phase) {
- case 0:
- /*
- * PHASE 0.
- * Check that the set of tags associated with given structure
- * perfectly fits our expectations.
- */
-
- rval = ber_check_tags(opt_codec_ctx, td, ctx, ptr, size,
- tag_mode, 1, &ctx->left, 0);
- if(rval.code != RC_OK) {
- ASN_DEBUG("%s tagging check failed: %d",
- td->name, rval.code);
- return rval;
- }
-
- if(ctx->left >= 0)
- ctx->left += rval.consumed; /* ?Substracted below! */
- ADVANCE(rval.consumed);
-
- NEXT_PHASE(ctx);
-
- ASN_DEBUG("Structure consumes %ld bytes, buffer %ld",
- (long)ctx->left, (long)size);
-
- /* Fall through */
- case 1:
- /*
- * PHASE 1.
- * From the place where we've left it previously,
- * try to decode the next member from the list of
- * this structure's elements.
- * (ctx->step) stores the member being processed
- * between invocations and the microphase {0,1} of parsing
- * that member:
- * step = (<member_number> * 2 + <microphase>).
- */
- for(edx = (ctx->step >> 1); edx < td->elements_count;
- edx++, ctx->step = (ctx->step & ~1) + 2) {
- void *memb_ptr; /* Pointer to the member */
- void **memb_ptr2; /* Pointer to that pointer */
- ssize_t tag_len; /* Length of TLV's T */
- int opt_edx_end; /* Next non-optional element */
- int use_bsearch;
- int n;
-
- if(ctx->step & 1)
- goto microphase2;
-
- /*
- * MICROPHASE 1: Synchronize decoding.
- */
- ASN_DEBUG("In %s SEQUENCE left %d, edx=%d flags=%d"
- " opt=%d ec=%d",
- td->name, (int)ctx->left, edx,
- elements[edx].flags, elements[edx].optional,
- td->elements_count);
-
- if(ctx->left == 0 /* No more stuff is expected */
- && (
- /* Explicit OPTIONAL specification reaches the end */
- (edx + elements[edx].optional
- == td->elements_count)
- ||
- /* All extensions are optional */
- (IN_EXTENSION_GROUP(specs, edx)
- && specs->ext_before > td->elements_count)
- )
- ) {
- ASN_DEBUG("End of SEQUENCE %s", td->name);
- /*
- * Found the legitimate end of the structure.
- */
- PHASE_OUT(ctx);
- RETURN(RC_OK);
- }
-
- /*
- * Fetch the T from TLV.
- */
- tag_len = ber_fetch_tag(ptr, LEFT, &tlv_tag);
- ASN_DEBUG("Current tag in %s SEQUENCE for element %d "
- "(%s) is %s encoded in %d bytes, of frame %ld",
- td->name, edx, elements[edx].name,
- ber_tlv_tag_string(tlv_tag), (int)tag_len, (long)LEFT);
- switch(tag_len) {
- case 0: if(!SIZE_VIOLATION) RETURN(RC_WMORE);
- /* Fall through */
- case -1: RETURN(RC_FAIL);
- }
-
- if(ctx->left < 0 && ((const uint8_t *)ptr)[0] == 0) {
- if(LEFT < 2) {
- if(SIZE_VIOLATION)
- RETURN(RC_FAIL);
- else
- RETURN(RC_WMORE);
- } else if(((const uint8_t *)ptr)[1] == 0) {
- ASN_DEBUG("edx = %d, opt = %d, ec=%d",
- edx, elements[edx].optional,
- td->elements_count);
- if((edx + elements[edx].optional
- == td->elements_count)
- || (IN_EXTENSION_GROUP(specs, edx)
- && specs->ext_before
- > td->elements_count)) {
- /*
- * Yeah, baby! Found the terminator
- * of the indefinite length structure.
- */
- /*
- * Proceed to the canonical
- * finalization function.
- * No advancing is necessary.
- */
- goto phase3;
- }
- }
- }
-
- /*
- * Find the next available type with this tag.
- */
- use_bsearch = 0;
- opt_edx_end = edx + elements[edx].optional + 1;
- if(opt_edx_end > td->elements_count)
- opt_edx_end = td->elements_count; /* Cap */
- else if(opt_edx_end - edx > 8) {
- /* Limit the scope of linear search... */
- opt_edx_end = edx + 8;
- use_bsearch = 1;
- /* ... and resort to bsearch() */
- }
- for(n = edx; n < opt_edx_end; n++) {
- if(BER_TAGS_EQUAL(tlv_tag, elements[n].tag)) {
- /*
- * Found element corresponding to the tag
- * being looked at.
- * Reposition over the right element.
- */
- edx = n;
- ctx->step = 1 + 2 * edx; /* Remember! */
- goto microphase2;
- } else if(elements[n].flags & ATF_OPEN_TYPE) {
- /*
- * This is the ANY type, which may bear
- * any flag whatsoever.
- */
- edx = n;
- ctx->step = 1 + 2 * edx; /* Remember! */
- goto microphase2;
- } else if(elements[n].tag == (ber_tlv_tag_t)-1) {
- use_bsearch = 1;
- break;
- }
- }
- if(use_bsearch) {
- /*
- * Resort to a binary search over
- * sorted array of tags.
- */
- asn_TYPE_tag2member_t *t2m;
- asn_TYPE_tag2member_t key;
- key.el_tag = tlv_tag;
- key.el_no = edx;
- t2m = (asn_TYPE_tag2member_t *)bsearch(&key,
- specs->tag2el, specs->tag2el_count,
- sizeof(specs->tag2el[0]), _t2e_cmp);
- if(t2m) {
- asn_TYPE_tag2member_t *best = 0;
- asn_TYPE_tag2member_t *t2m_f, *t2m_l;
- int edx_max = edx + elements[edx].optional;
- /*
- * Rewind to the first element with that tag,
- * `cause bsearch() does not guarantee order.
- */
- t2m_f = t2m + t2m->toff_first;
- t2m_l = t2m + t2m->toff_last;
- for(t2m = t2m_f; t2m <= t2m_l; t2m++) {
- if(t2m->el_no > edx_max) break;
- if(t2m->el_no < edx) continue;
- best = t2m;
- }
- if(best) {
- edx = best->el_no;
- ctx->step = 1 + 2 * edx;
- goto microphase2;
- }
- }
- n = opt_edx_end;
- }
- if(n == opt_edx_end) {
- /*
- * If tag is unknown, it may be either
- * an unknown (thus, incorrect) tag,
- * or an extension (...),
- * or an end of the indefinite-length structure.
- */
- if(!IN_EXTENSION_GROUP(specs, edx)) {
- ASN_DEBUG("Unexpected tag %s (at %d)",
- ber_tlv_tag_string(tlv_tag), edx);
- ASN_DEBUG("Expected tag %s (%s)%s",
- ber_tlv_tag_string(elements[edx].tag),
- elements[edx].name,
- elements[edx].optional
- ?" or alternatives":"");
- RETURN(RC_FAIL);
- } else {
- /* Skip this tag */
- ssize_t skip;
-
- skip = ber_skip_length(opt_codec_ctx,
- BER_TLV_CONSTRUCTED(ptr),
- (const char *)ptr + tag_len,
- LEFT - tag_len);
- ASN_DEBUG("Skip length %d in %s",
- (int)skip, td->name);
- switch(skip) {
- case 0: if(!SIZE_VIOLATION) RETURN(RC_WMORE);
- /* Fall through */
- case -1: RETURN(RC_FAIL);
- }
-
- ADVANCE(skip + tag_len);
- ctx->step -= 2;
- edx--;
- continue; /* Try again with the next tag */
- }
- }
-
- /*
- * MICROPHASE 2: Invoke the member-specific decoder.
- */
- ctx->step |= 1; /* Confirm entering next microphase */
- microphase2:
- ASN_DEBUG("Inside SEQUENCE %s MF2", td->name);
-
- /*
- * Compute the position of the member inside a structure,
- * and also a type of containment (it may be contained
- * as pointer or using inline inclusion).
- */
- if(elements[edx].flags & ATF_POINTER) {
- /* Member is a pointer to another structure */
- memb_ptr2 = (void **)((char *)st + elements[edx].memb_offset);
- } else {
- /*
- * A pointer to a pointer
- * holding the start of the structure
- */
- memb_ptr = (char *)st + elements[edx].memb_offset;
- memb_ptr2 = &memb_ptr;
- }
- /*
- * Invoke the member fetch routine according to member's type
- */
- rval = elements[edx].type->ber_decoder(opt_codec_ctx,
- elements[edx].type,
- memb_ptr2, ptr, LEFT,
- elements[edx].tag_mode);
- ASN_DEBUG("In %s SEQUENCE decoded %d %s of %d "
- "in %d bytes rval.code %d, size=%d",
- td->name, edx, elements[edx].type->name,
- (int)LEFT, (int)rval.consumed, rval.code, (int)size);
- switch(rval.code) {
- case RC_OK:
- break;
- case RC_WMORE: /* More data expected */
- if(!SIZE_VIOLATION) {
- ADVANCE(rval.consumed);
- RETURN(RC_WMORE);
- }
- ASN_DEBUG("Size violation (c->l=%ld <= s=%ld)",
- (long)ctx->left, (long)size);
- /* Fall through */
- case RC_FAIL: /* Fatal error */
- RETURN(RC_FAIL);
- } /* switch(rval) */
-
- ADVANCE(rval.consumed);
- } /* for(all structure members) */
-
- phase3:
- ctx->phase = 3;
- case 3: /* 00 and other tags expected */
- case 4: /* only 00's expected */
-
- ASN_DEBUG("SEQUENCE %s Leftover: %ld, size = %ld",
- td->name, (long)ctx->left, (long)size);
-
- /*
- * Skip everything until the end of the SEQUENCE.
- */
- while(ctx->left) {
- ssize_t tl, ll;
-
- tl = ber_fetch_tag(ptr, LEFT, &tlv_tag);
- switch(tl) {
- case 0: if(!SIZE_VIOLATION) RETURN(RC_WMORE);
- /* Fall through */
- case -1: RETURN(RC_FAIL);
- }
-
- /*
- * If expected <0><0>...
- */
- if(ctx->left < 0
- && ((const uint8_t *)ptr)[0] == 0) {
- if(LEFT < 2) {
- if(SIZE_VIOLATION)
- RETURN(RC_FAIL);
- else
- RETURN(RC_WMORE);
- } else if(((const uint8_t *)ptr)[1] == 0) {
- /*
- * Correctly finished with <0><0>.
- */
- ADVANCE(2);
- ctx->left++;
- ctx->phase = 4;
- continue;
- }
- }
-
- if(!IN_EXTENSION_GROUP(specs, td->elements_count)
- || ctx->phase == 4) {
- ASN_DEBUG("Unexpected continuation "
- "of a non-extensible type "
- "%s (SEQUENCE): %s",
- td->name,
- ber_tlv_tag_string(tlv_tag));
- RETURN(RC_FAIL);
- }
-
- ll = ber_skip_length(opt_codec_ctx,
- BER_TLV_CONSTRUCTED(ptr),
- (const char *)ptr + tl, LEFT - tl);
- switch(ll) {
- case 0: if(!SIZE_VIOLATION) RETURN(RC_WMORE);
- /* Fall through */
- case -1: RETURN(RC_FAIL);
- }
-
- ADVANCE(tl + ll);
- }
-
- PHASE_OUT(ctx);
- }
-
- RETURN(RC_OK);
-}
-
-
-/*
- * The DER encoder of the SEQUENCE type.
- */
-asn_enc_rval_t
-SEQUENCE_encode_der(asn_TYPE_descriptor_t *td,
- void *sptr, int tag_mode, ber_tlv_tag_t tag,
- asn_app_consume_bytes_f *cb, void *app_key) {
- size_t computed_size = 0;
- asn_enc_rval_t erval;
- ssize_t ret;
- int edx;
-
- ASN_DEBUG("%s %s as SEQUENCE",
- cb?"Encoding":"Estimating", td->name);
-
- /*
- * Gather the length of the underlying members sequence.
- */
- for(edx = 0; edx < td->elements_count; edx++) {
- asn_TYPE_member_t *elm = &td->elements[edx];
- void *memb_ptr;
- if(elm->flags & ATF_POINTER) {
- memb_ptr = *(void **)((char *)sptr + elm->memb_offset);
- if(!memb_ptr) {
- if(elm->optional) continue;
- /* Mandatory element is missing */
- _ASN_ENCODE_FAILED;
- }
- } else {
- memb_ptr = (void *)((char *)sptr + elm->memb_offset);
- }
- erval = elm->type->der_encoder(elm->type, memb_ptr,
- elm->tag_mode, elm->tag,
- 0, 0);
- if(erval.encoded == -1)
- return erval;
- computed_size += erval.encoded;
- ASN_DEBUG("Member %d %s estimated %ld bytes",
- edx, elm->name, (long)erval.encoded);
- }
-
- /*
- * Encode the TLV for the sequence itself.
- */
- ret = der_write_tags(td, computed_size, tag_mode, 1, tag, cb, app_key);
- ASN_DEBUG("Wrote tags: %ld (+%ld)", (long)ret, (long)computed_size);
- if(ret == -1)
- _ASN_ENCODE_FAILED;
- erval.encoded = computed_size + ret;
-
- if(!cb) _ASN_ENCODED_OK(erval);
-
- /*
- * Encode all members.
- */
- for(edx = 0; edx < td->elements_count; edx++) {
- asn_TYPE_member_t *elm = &td->elements[edx];
- asn_enc_rval_t tmperval;
- void *memb_ptr;
-
- if(elm->flags & ATF_POINTER) {
- memb_ptr = *(void **)((char *)sptr + elm->memb_offset);
- if(!memb_ptr) continue;
- } else {
- memb_ptr = (void *)((char *)sptr + elm->memb_offset);
- }
- tmperval = elm->type->der_encoder(elm->type, memb_ptr,
- elm->tag_mode, elm->tag,
- cb, app_key);
- if(tmperval.encoded == -1)
- return tmperval;
- computed_size -= tmperval.encoded;
- ASN_DEBUG("Member %d %s of SEQUENCE %s encoded in %ld bytes",
- edx, elm->name, td->name, (long)tmperval.encoded);
- }
-
- if(computed_size != 0)
- /*
- * Encoded size is not equal to the computed size.
- */
- _ASN_ENCODE_FAILED;
-
- _ASN_ENCODED_OK(erval);
-}
-
-
-#undef XER_ADVANCE
-#define XER_ADVANCE(num_bytes) do { \
- size_t num = num_bytes; \
- buf_ptr = ((const char *)buf_ptr) + num;\
- size -= num; \
- consumed_myself += num; \
- } while(0)
-
-/*
- * Decode the XER (XML) data.
- */
-asn_dec_rval_t
-SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
- void **struct_ptr, const char *opt_mname,
- const void *buf_ptr, size_t size) {
- /*
- * Bring closer parts of structure description.
- */
- asn_SEQUENCE_specifics_t *specs
- = (asn_SEQUENCE_specifics_t *)td->specifics;
- asn_TYPE_member_t *elements = td->elements;
- const char *xml_tag = opt_mname ? opt_mname : td->xml_tag;
-
- /*
- * ... and parts of the structure being constructed.
- */
- void *st = *struct_ptr; /* Target structure. */
- asn_struct_ctx_t *ctx; /* Decoder context */
-
- asn_dec_rval_t rval; /* Return value from a decoder */
- ssize_t consumed_myself = 0; /* Consumed bytes from ptr */
- int edx; /* Element index */
- int edx_end;
-
- /*
- * Create the target structure if it is not present already.
- */
- if(st == 0) {
- st = *struct_ptr = CALLOC(1, specs->struct_size);
- if(st == 0) RETURN(RC_FAIL);
- }
-
- /*
- * Restore parsing context.
- */
- ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset);
-
-
- /*
- * Phases of XER/XML processing:
- * Phase 0: Check that the opening tag matches our expectations.
- * Phase 1: Processing body and reacting on closing tag.
- * Phase 2: Processing inner type.
- * Phase 3: Skipping unknown extensions.
- * Phase 4: PHASED OUT
- */
- for(edx = ctx->step; ctx->phase <= 3;) {
- pxer_chunk_type_e ch_type; /* XER chunk type */
- ssize_t ch_size; /* Chunk size */
- xer_check_tag_e tcv; /* Tag check value */
- asn_TYPE_member_t *elm;
- int n;
-
- /*
- * Go inside the inner member of a sequence.
- */
- if(ctx->phase == 2) {
- asn_dec_rval_t tmprval;
- void *memb_ptr; /* Pointer to the member */
- void **memb_ptr2; /* Pointer to that pointer */
-
- elm = &td->elements[edx];
-
- if(elm->flags & ATF_POINTER) {
- /* Member is a pointer to another structure */
- memb_ptr2 = (void **)((char *)st
- + elm->memb_offset);
- } else {
- memb_ptr = (char *)st + elm->memb_offset;
- memb_ptr2 = &memb_ptr;
- }
-
- /* Invoke the inner type decoder, m.b. multiple times */
- tmprval = elm->type->xer_decoder(opt_codec_ctx,
- elm->type, memb_ptr2, elm->name,
- buf_ptr, size);
- XER_ADVANCE(tmprval.consumed);
- if(tmprval.code != RC_OK)
- RETURN(tmprval.code);
- ctx->phase = 1; /* Back to body processing */
- ctx->step = ++edx;
- ASN_DEBUG("XER/SEQUENCE phase => %d, step => %d",
- ctx->phase, ctx->step);
- /* Fall through */
- }
-
- /*
- * Get the next part of the XML stream.
- */
- ch_size = xer_next_token(&ctx->context, buf_ptr, size,
- &ch_type);
- switch(ch_size) {
- case -1: RETURN(RC_FAIL);
- case 0: RETURN(RC_WMORE);
- default:
- switch(ch_type) {
- case PXER_COMMENT: /* Got XML comment */
- case PXER_TEXT: /* Ignore free-standing text */
- XER_ADVANCE(ch_size); /* Skip silently */
- continue;
- case PXER_TAG:
- break; /* Check the rest down there */
- }
- }
-
- tcv = xer_check_tag(buf_ptr, ch_size, xml_tag);
- ASN_DEBUG("XER/SEQUENCE: tcv = %d, ph=%d [%s]",
- tcv, ctx->phase, xml_tag);
-
- /* Skip the extensions section */
- if(ctx->phase == 3) {
- switch(xer_skip_unknown(tcv, &ctx->left)) {
- case -1:
- ctx->phase = 4;
- RETURN(RC_FAIL);
- case 0:
- XER_ADVANCE(ch_size);
- continue;
- case 1:
- XER_ADVANCE(ch_size);
- ctx->phase = 1;
- continue;
- case 2:
- ctx->phase = 1;
- break;
- }
- }
-
- switch(tcv) {
- case XCT_CLOSING:
- if(ctx->phase == 0) break;
- ctx->phase = 0;
- /* Fall through */
- case XCT_BOTH:
- if(ctx->phase == 0) {
- if(edx >= td->elements_count
- ||
- /* Explicit OPTIONAL specs reaches the end */
- (edx + elements[edx].optional
- == td->elements_count)
- ||
- /* All extensions are optional */
- (IN_EXTENSION_GROUP(specs, edx)
- && specs->ext_before
- > td->elements_count)
- ) {
- XER_ADVANCE(ch_size);
- ctx->phase = 4; /* Phase out */
- RETURN(RC_OK);
- } else {
- ASN_DEBUG("Premature end of XER SEQUENCE");
- RETURN(RC_FAIL);
- }
- }
- /* Fall through */
- case XCT_OPENING:
- if(ctx->phase == 0) {
- XER_ADVANCE(ch_size);
- ctx->phase = 1; /* Processing body phase */
- continue;
- }
- /* Fall through */
- case XCT_UNKNOWN_OP:
- case XCT_UNKNOWN_BO:
-
- ASN_DEBUG("XER/SEQUENCE: tcv=%d, ph=%d, edx=%d",
- tcv, ctx->phase, edx);
- if(ctx->phase != 1) {
- break; /* Really unexpected */
- }
-
- if(edx < td->elements_count) {
- /*
- * Search which member corresponds to this tag.
- */
- edx_end = edx + elements[edx].optional + 1;
- if(edx_end > td->elements_count)
- edx_end = td->elements_count;
- for(n = edx; n < edx_end; n++) {
- elm = &td->elements[n];
- tcv = xer_check_tag(buf_ptr,
- ch_size, elm->name);
- switch(tcv) {
- case XCT_BOTH:
- case XCT_OPENING:
- /*
- * Process this member.
- */
- ctx->step = edx = n;
- ctx->phase = 2;
- break;
- case XCT_UNKNOWN_OP:
- case XCT_UNKNOWN_BO:
- continue;
- default:
- n = edx_end;
- break; /* Phase out */
- }
- break;
- }
- if(n != edx_end)
- continue;
- } else {
- ASN_DEBUG("Out of defined members: %d/%d",
- edx, td->elements_count);
- }
-
- /* It is expected extension */
- if(IN_EXTENSION_GROUP(specs,
- edx + (edx < td->elements_count
- ? elements[edx].optional : 0))) {
- ASN_DEBUG("Got anticipated extension at %d",
- edx);
- /*
- * Check for (XCT_BOTH or XCT_UNKNOWN_BO)
- * By using a mask. Only record a pure
- * <opening> tags.
- */
- if(tcv & XCT_CLOSING) {
- /* Found </extension> without body */
- } else {
- ctx->left = 1;
- ctx->phase = 3; /* Skip ...'s */
- }
- XER_ADVANCE(ch_size);
- continue;
- }
-
- /* Fall through */
- default:
- break;
- }
-
- ASN_DEBUG("Unexpected XML tag in SEQUENCE [%c%c%c%c%c%c]",
- size>0?((const char *)buf_ptr)[0]:'.',
- size>1?((const char *)buf_ptr)[1]:'.',
- size>2?((const char *)buf_ptr)[2]:'.',
- size>3?((const char *)buf_ptr)[3]:'.',
- size>4?((const char *)buf_ptr)[4]:'.',
- size>5?((const char *)buf_ptr)[5]:'.');
- break;
- }
-
- ctx->phase = 4; /* "Phase out" on hard failure */
- RETURN(RC_FAIL);
-}
-
-asn_enc_rval_t
-SEQUENCE_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
- int ilevel, enum xer_encoder_flags_e flags,
- asn_app_consume_bytes_f *cb, void *app_key) {
- asn_enc_rval_t er;
- int xcan = (flags & XER_F_CANONICAL);
- int edx;
-
- if(!sptr)
- _ASN_ENCODE_FAILED;
-
- er.encoded = 0;
-
- for(edx = 0; edx < td->elements_count; edx++) {
- asn_enc_rval_t tmper;
- asn_TYPE_member_t *elm = &td->elements[edx];
- void *memb_ptr;
- const char *mname = elm->name;
- unsigned int mlen = strlen(mname);
-
- if(elm->flags & ATF_POINTER) {
- memb_ptr = *(void **)((char *)sptr + elm->memb_offset);
- if(!memb_ptr) {
- if(elm->optional)
- continue;
- /* Mandatory element is missing */
- _ASN_ENCODE_FAILED;
- }
- } else {
- memb_ptr = (void *)((char *)sptr + elm->memb_offset);
- }
-
- if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel);
- _ASN_CALLBACK3("<", 1, mname, mlen, ">", 1);
-
- /* Print the member itself */
- tmper = elm->type->xer_encoder(elm->type, memb_ptr,
- ilevel + 1, flags, cb, app_key);
- if(tmper.encoded == -1) return tmper;
-
- _ASN_CALLBACK3("</", 2, mname, mlen, ">", 1);
- er.encoded += 5 + (2 * mlen) + tmper.encoded;
- }
-
- if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel - 1);
-
- _ASN_ENCODED_OK(er);
-cb_failed:
- _ASN_ENCODE_FAILED;
-}
-
-int
-SEQUENCE_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
- asn_app_consume_bytes_f *cb, void *app_key) {
- int edx;
- int ret;
-
- if(!sptr) return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
-
- /* Dump preamble */
- if(cb(td->name, strlen(td->name), app_key) < 0
- || cb(" ::= {", 6, app_key) < 0)
- return -1;
-
- for(edx = 0; edx < td->elements_count; edx++) {
- asn_TYPE_member_t *elm = &td->elements[edx];
- const void *memb_ptr;
-
- if(elm->flags & ATF_POINTER) {
- memb_ptr = *(const void * const *)((const char *)sptr + elm->memb_offset);
- if(!memb_ptr) {
- if(elm->optional) continue;
- /* Print <absent> line */
- /* Fall through */
- }
- } else {
- memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
- }
-
- /* Indentation */
- _i_INDENT(1);
-
- /* Print the member's name and stuff */
- if(cb(elm->name, strlen(elm->name), app_key) < 0
- || cb(": ", 2, app_key) < 0)
- return -1;
-
- /* Print the member itself */
- ret = elm->type->print_struct(elm->type, memb_ptr, ilevel + 1,
- cb, app_key);
- if(ret) return ret;
- }
-
- ilevel--;
- _i_INDENT(1);
-
- return (cb("}", 1, app_key) < 0) ? -1 : 0;
-}
-
-void
-SEQUENCE_free(asn_TYPE_descriptor_t *td, void *sptr, int contents_only) {
- int edx;
-
- if(!td || !sptr)
- return;
-
- ASN_DEBUG("Freeing %s as SEQUENCE", td->name);
-
- for(edx = 0; edx < td->elements_count; edx++) {
- asn_TYPE_member_t *elm = &td->elements[edx];
- void *memb_ptr;
- if(elm->flags & ATF_POINTER) {
- memb_ptr = *(void **)((char *)sptr + elm->memb_offset);
- if(memb_ptr)
- ASN_STRUCT_FREE(*elm->type, memb_ptr);
- } else {
- memb_ptr = (void *)((char *)sptr + elm->memb_offset);
- ASN_STRUCT_FREE_CONTENTS_ONLY(*elm->type, memb_ptr);
- }
- }
-
- if(!contents_only) {
- FREEMEM(sptr);
- }
-}
-
-int
-SEQUENCE_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
- asn_app_constraint_failed_f *ctfailcb, void *app_key) {
- int edx;
-
- if(!sptr) {
- _ASN_CTFAIL(app_key, td,
- "%s: value not given (%s:%d)",
- td->name, __FILE__, __LINE__);
- return -1;
- }
-
- /*
- * Iterate over structure members and check their validity.
- */
- for(edx = 0; edx < td->elements_count; edx++) {
- asn_TYPE_member_t *elm = &td->elements[edx];
- const void *memb_ptr;
-
- if(elm->flags & ATF_POINTER) {
- memb_ptr = *(const void * const *)((const char *)sptr + elm->memb_offset);
- if(!memb_ptr) {
- if(elm->optional)
- continue;
- _ASN_CTFAIL(app_key, td,
- "%s: mandatory element %s absent (%s:%d)",
- td->name, elm->name, __FILE__, __LINE__);
- return -1;
- }
- } else {
- memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
- }
-
- if(elm->memb_constraints) {
- int ret = elm->memb_constraints(elm->type, memb_ptr,
- ctfailcb, app_key);
- if(ret) return ret;
- } else {
- int ret = elm->type->check_constraints(elm->type,
- memb_ptr, ctfailcb, app_key);
- if(ret) return ret;
- /*
- * Cannot inherit it earlier:
- * need to make sure we get the updated version.
- */
- elm->memb_constraints = elm->type->check_constraints;
- }
- }
-
- return 0;
-}
-
-asn_dec_rval_t
-SEQUENCE_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
- asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
- asn_SEQUENCE_specifics_t *specs = (asn_SEQUENCE_specifics_t *)td->specifics;
- void *st = *sptr; /* Target structure. */
- int extpresent = 0; /* Extension additions are present */
- uint8_t *opres; /* Presence of optional root members */
- asn_per_data_t opmd;
- asn_dec_rval_t rv;
- int edx;
-
- (void)constraints;
-
- if(_ASN_STACK_OVERFLOW_CHECK(opt_codec_ctx))
- _ASN_DECODE_FAILED;
-
- if(!st) {
- st = *sptr = CALLOC(1, specs->struct_size);
- if(!st) _ASN_DECODE_FAILED;
- }
-
- ASN_DEBUG("Decoding %s as SEQUENCE (UPER)", td->name);
-
- /* Handle extensions */
- if(specs->ext_before >= 0) {
- extpresent = per_get_few_bits(pd, 1);
- if(extpresent < 0) _ASN_DECODE_STARVED;
- }
-
- /* Prepare a place and read-in the presence bitmap */
- if(specs->roms_count) {
- opres = (uint8_t *)MALLOC(((specs->roms_count + 7) >> 3) + 1);
- if(!opres) _ASN_DECODE_FAILED;
- /* Get the presence map */
- if(per_get_many_bits(pd, opres, 0, specs->roms_count)) {
- FREEMEM(opres);
- _ASN_DECODE_STARVED;
- }
- opmd.buffer = opres;
- opmd.nboff = 0;
- opmd.nbits = specs->roms_count;
- ASN_DEBUG("Read in presence bitmap for %s of %d bits (%x..)",
- td->name, specs->roms_count, *opres);
- } else {
- opres = 0;
- memset(&opmd, 0, sizeof opmd);
- }
-
- /*
- * Get the sequence ROOT elements.
- */
- for(edx = 0; edx < ((specs->ext_before < 0)
- ? td->elements_count : specs->ext_before + 1); edx++) {
- asn_TYPE_member_t *elm = &td->elements[edx];
- void *memb_ptr; /* Pointer to the member */
- void **memb_ptr2; /* Pointer to that pointer */
-
- /* Fetch the pointer to this member */
- if(elm->flags & ATF_POINTER) {
- memb_ptr2 = (void **)((char *)st + elm->memb_offset);
- } else {
- memb_ptr = (char *)st + elm->memb_offset;
- memb_ptr2 = &memb_ptr;
- }
-
- /* Deal with optionality */
- if(elm->optional) {
- int present = per_get_few_bits(&opmd, 1);
- ASN_DEBUG("Member %s->%s is optional, p=%d (%d->%d)",
- td->name, elm->name, present,
- (int)opmd.nboff, (int)opmd.nbits);
- if(present == 0) {
- /* This element is not present */
- if(elm->default_value) {
- /* Fill-in DEFAULT */
- if(elm->default_value(1, memb_ptr2)) {
- FREEMEM(opres);
- _ASN_DECODE_FAILED;
- }
- }
- /* The member is just not present */
- continue;
- }
- /* Fall through */
- }
-
- /* Fetch the member from the stream */
- ASN_DEBUG("Decoding member %s in %s", elm->name, td->name);
- rv = elm->type->uper_decoder(opt_codec_ctx, elm->type,
- elm->per_constraints, memb_ptr2, pd);
- if(rv.code != RC_OK) {
- ASN_DEBUG("Failed decode %s in %s",
- elm->name, td->name);
- FREEMEM(opres);
- return rv;
- }
- }
-
- /*
- * Deal with extensions.
- */
- if(extpresent) {
- ASN_DEBUG("Extensibility for %s: NOT IMPLEMENTED", td->name);
- _ASN_DECODE_FAILED;
- } else {
- for(edx = specs->roms_count; edx < specs->roms_count
- + specs->aoms_count; edx++) {
- asn_TYPE_member_t *elm = &td->elements[edx];
- void *memb_ptr; /* Pointer to the member */
- void **memb_ptr2; /* Pointer to that pointer */
-
- if(!elm->default_value) continue;
-
- /* Fetch the pointer to this member */
- if(elm->flags & ATF_POINTER) {
- memb_ptr2 = (void **)((char *)st
- + elm->memb_offset);
- } else {
- memb_ptr = (char *)st + elm->memb_offset;
- memb_ptr2 = &memb_ptr;
- }
-
- /* Set default value */
- if(elm->default_value(1, memb_ptr2)) {
- FREEMEM(opres);
- _ASN_DECODE_FAILED;
- }
- }
- }
-
- rv.consumed = 0;
- rv.code = RC_OK;
- FREEMEM(opres);
- return rv;
-}
-
-asn_enc_rval_t
-SEQUENCE_encode_uper(asn_TYPE_descriptor_t *td,
- asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
- asn_SEQUENCE_specifics_t *specs
- = (asn_SEQUENCE_specifics_t *)td->specifics;
- asn_enc_rval_t er;
- int edx;
- int i;
-
- (void)constraints;
-
- if(!sptr)
- _ASN_ENCODE_FAILED;
-
- er.encoded = 0;
-
- ASN_DEBUG("Encoding %s as SEQUENCE (UPER)", td->name);
- if(specs->ext_before >= 0)
- _ASN_ENCODE_FAILED; /* We don't encode extensions yet */
-
- /* Encode a presence bitmap */
- for(i = 0; i < specs->roms_count; i++) {
- asn_TYPE_member_t *elm;
- void *memb_ptr; /* Pointer to the member */
- void **memb_ptr2; /* Pointer to that pointer */
- int present;
-
- edx = specs->oms[i];
- elm = &td->elements[edx];
-
- /* Fetch the pointer to this member */
- if(elm->flags & ATF_POINTER) {
- memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
- present = (*memb_ptr2 != 0);
- } else {
- memb_ptr = (void *)((char *)sptr + elm->memb_offset);
- memb_ptr2 = &memb_ptr;
- present = 1;
- }
-
- /* Eliminate default values */
- if(present && elm->default_value
- && elm->default_value(0, memb_ptr2) == 1)
- present = 0;
-
- ASN_DEBUG("Element %s %s %s->%s is %s",
- elm->flags & ATF_POINTER ? "ptr" : "inline",
- elm->default_value ? "def" : "wtv",
- td->name, elm->name, present ? "present" : "absent");
- if(per_put_few_bits(po, present, 1))
- _ASN_ENCODE_FAILED;
- }
-
- /*
- * Get the sequence ROOT elements.
- */
- for(edx = 0; edx < ((specs->ext_before < 0)
- ? td->elements_count : specs->ext_before + 1); edx++) {
- asn_TYPE_member_t *elm = &td->elements[edx];
- void *memb_ptr; /* Pointer to the member */
- void **memb_ptr2; /* Pointer to that pointer */
-
- /* Fetch the pointer to this member */
- if(elm->flags & ATF_POINTER) {
- memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
- if(!*memb_ptr2) {
- ASN_DEBUG("Element %s %d not present",
- elm->name, edx);
- if(elm->optional)
- continue;
- /* Mandatory element is missing */
- _ASN_ENCODE_FAILED;
- }
- } else {
- memb_ptr = (void *)((char *)sptr + elm->memb_offset);
- memb_ptr2 = &memb_ptr;
- }
-
- /* Eliminate default values */
- if(elm->default_value && elm->default_value(0, memb_ptr2) == 1)
- continue;
-
- er = elm->type->uper_encoder(elm->type, elm->per_constraints,
- *memb_ptr2, po);
- if(er.encoded == -1)
- return er;
- }
-
- _ASN_ENCODED_OK(er);
-}
-
+++ /dev/null
-/*-
- * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-#ifndef _CONSTR_SEQUENCE_H_
-#define _CONSTR_SEQUENCE_H_
-
-#include <asn_application.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct asn_SEQUENCE_specifics_s {
- /*
- * Target structure description.
- */
- int struct_size; /* Size of the target structure. */
- int ctx_offset; /* Offset of the asn_struct_ctx_t member */
-
- /*
- * Tags to members mapping table (sorted).
- */
- asn_TYPE_tag2member_t *tag2el;
- int tag2el_count;
-
- /*
- * Optional members of the extensions root (roms) or additions (aoms).
- * Meaningful for PER.
- */
- int *oms; /* Optional MemberS */
- int roms_count; /* Root optional members count */
- int aoms_count; /* Additions optional members count */
-
- /*
- * Description of an extensions group.
- */
- int ext_after; /* Extensions start after this member */
- int ext_before; /* Extensions stop before this member */
-} asn_SEQUENCE_specifics_t;
-
-
-/*
- * A set specialized functions dealing with the SEQUENCE type.
- */
-asn_struct_free_f SEQUENCE_free;
-asn_struct_print_f SEQUENCE_print;
-asn_constr_check_f SEQUENCE_constraint;
-ber_type_decoder_f SEQUENCE_decode_ber;
-der_type_encoder_f SEQUENCE_encode_der;
-xer_type_decoder_f SEQUENCE_decode_xer;
-xer_type_encoder_f SEQUENCE_encode_xer;
-per_type_decoder_f SEQUENCE_decode_uper;
-per_type_encoder_f SEQUENCE_encode_uper;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _CONSTR_SEQUENCE_H_ */
+++ /dev/null
-/*-
- * Copyright (c) 2003, 2004, 2006 Lev Walkin <vlm@lionet.info>.
- * All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-#include <asn_internal.h>
-#include <constr_SEQUENCE_OF.h>
-#include <asn_SEQUENCE_OF.h>
-
-/*
- * The DER encoder of the SEQUENCE OF type.
- */
-asn_enc_rval_t
-SEQUENCE_OF_encode_der(asn_TYPE_descriptor_t *td, void *ptr,
- int tag_mode, ber_tlv_tag_t tag,
- asn_app_consume_bytes_f *cb, void *app_key) {
- asn_TYPE_member_t *elm = td->elements;
- asn_anonymous_sequence_ *list = _A_SEQUENCE_FROM_VOID(ptr);
- size_t computed_size = 0;
- ssize_t encoding_size = 0;
- asn_enc_rval_t erval;
- int edx;
-
- ASN_DEBUG("Estimating size of SEQUENCE OF %s", td->name);
-
- /*
- * Gather the length of the underlying members sequence.
- */
- for(edx = 0; edx < list->count; edx++) {
- void *memb_ptr = list->array[edx];
- if(!memb_ptr) continue;
- erval = elm->type->der_encoder(elm->type, memb_ptr,
- 0, elm->tag,
- 0, 0);
- if(erval.encoded == -1)
- return erval;
- computed_size += erval.encoded;
- }
-
- /*
- * Encode the TLV for the sequence itself.
- */
- encoding_size = der_write_tags(td, computed_size, tag_mode, 1, tag,
- cb, app_key);
- if(encoding_size == -1) {
- erval.encoded = -1;
- erval.failed_type = td;
- erval.structure_ptr = ptr;
- return erval;
- }
-
- computed_size += encoding_size;
- if(!cb) {
- erval.encoded = computed_size;
- _ASN_ENCODED_OK(erval);
- }
-
- ASN_DEBUG("Encoding members of SEQUENCE OF %s", td->name);
-
- /*
- * Encode all members.
- */
- for(edx = 0; edx < list->count; edx++) {
- void *memb_ptr = list->array[edx];
- if(!memb_ptr) continue;
- erval = elm->type->der_encoder(elm->type, memb_ptr,
- 0, elm->tag,
- cb, app_key);
- if(erval.encoded == -1)
- return erval;
- encoding_size += erval.encoded;
- }
-
- if(computed_size != (size_t)encoding_size) {
- /*
- * Encoded size is not equal to the computed size.
- */
- erval.encoded = -1;
- erval.failed_type = td;
- erval.structure_ptr = ptr;
- } else {
- erval.encoded = computed_size;
- erval.structure_ptr = 0;
- erval.failed_type = 0;
- }
-
- return erval;
-}
-
-asn_enc_rval_t
-SEQUENCE_OF_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
- int ilevel, enum xer_encoder_flags_e flags,
- asn_app_consume_bytes_f *cb, void *app_key) {
- asn_enc_rval_t er;
- asn_SET_OF_specifics_t *specs = (asn_SET_OF_specifics_t *)td->specifics;
- asn_TYPE_member_t *elm = td->elements;
- asn_anonymous_sequence_ *list = _A_SEQUENCE_FROM_VOID(sptr);
- const char *mname = specs->as_XMLValueList
- ? 0 : ((*elm->name) ? elm->name : elm->type->xml_tag);
- unsigned int mlen = mname ? strlen(mname) : 0;
- int xcan = (flags & XER_F_CANONICAL);
- int i;
-
- if(!sptr) _ASN_ENCODE_FAILED;
-
- er.encoded = 0;
-
- for(i = 0; i < list->count; i++) {
- asn_enc_rval_t tmper;
- void *memb_ptr = list->array[i];
- if(!memb_ptr) continue;
-
- if(mname) {
- if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel);
- _ASN_CALLBACK3("<", 1, mname, mlen, ">", 1);
- }
-
- tmper = elm->type->xer_encoder(elm->type, memb_ptr,
- ilevel + 1, flags, cb, app_key);
- if(tmper.encoded == -1) return tmper;
- if(tmper.encoded == 0 && specs->as_XMLValueList) {
- const char *name = elm->type->xml_tag;
- size_t len = strlen(name);
- if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel + 1);
- _ASN_CALLBACK3("<", 1, name, len, "/>", 2);
- }
-
- if(mname) {
- _ASN_CALLBACK3("</", 2, mname, mlen, ">", 1);
- er.encoded += 5;
- }
-
- er.encoded += (2 * mlen) + tmper.encoded;
- }
-
- if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel - 1);
-
- _ASN_ENCODED_OK(er);
-cb_failed:
- _ASN_ENCODE_FAILED;
-}
-
-asn_enc_rval_t
-SEQUENCE_OF_encode_uper(asn_TYPE_descriptor_t *td,
- asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
- asn_anonymous_sequence_ *list;
- asn_per_constraint_t *ct;
- asn_enc_rval_t er;
- asn_TYPE_member_t *elm = td->elements;
- int seq;
-
- if(!sptr) _ASN_ENCODE_FAILED;
- list = _A_SEQUENCE_FROM_VOID(sptr);
-
- er.encoded = 0;
-
- ASN_DEBUG("Encoding %s as SEQUENCE OF (%d)", td->name, list->count);
-
- if(constraints) ct = &constraints->size;
- else if(td->per_constraints) ct = &td->per_constraints->size;
- else ct = 0;
-
- /* If extensible constraint, check if size is in root */
- if(ct) {
- int not_in_root = (list->count < ct->lower_bound
- || list->count > ct->upper_bound);
- ASN_DEBUG("lb %ld ub %ld %s",
- ct->lower_bound, ct->upper_bound,
- ct->flags & APC_EXTENSIBLE ? "ext" : "fix");
- if(ct->flags & APC_EXTENSIBLE) {
- /* Declare whether size is in extension root */
- if(per_put_few_bits(po, not_in_root, 1))
- _ASN_ENCODE_FAILED;
- if(not_in_root) ct = 0;
- } else if(not_in_root && ct->effective_bits >= 0)
- _ASN_ENCODE_FAILED;
- }
-
- if(ct && ct->effective_bits >= 0) {
- /* X.691, #19.5: No length determinant */
- if(per_put_few_bits(po, list->count - ct->lower_bound,
- ct->effective_bits))
- _ASN_ENCODE_FAILED;
- }
-
- for(seq = -1; seq < list->count;) {
- ssize_t mayEncode;
- if(seq < 0) seq = 0;
- if(ct && ct->effective_bits >= 0) {
- mayEncode = list->count;
- } else {
- mayEncode = uper_put_length(po, list->count - seq);
- if(mayEncode < 0) _ASN_ENCODE_FAILED;
- }
-
- while(mayEncode--) {
- void *memb_ptr = list->array[seq++];
- if(!memb_ptr) _ASN_ENCODE_FAILED;
- er = elm->type->uper_encoder(elm->type,
- elm->per_constraints, memb_ptr, po);
- if(er.encoded == -1)
- _ASN_ENCODE_FAILED;
- }
- }
-
- _ASN_ENCODED_OK(er);
-}
-
+++ /dev/null
-/*-
- * Copyright (c) 2003, 2005 Lev Walkin <vlm@lionet.info>. All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-#ifndef _CONSTR_SEQUENCE_OF_H_
-#define _CONSTR_SEQUENCE_OF_H_
-
-#include <asn_application.h>
-#include <constr_SET_OF.h> /* Implemented using SET OF */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * A set specialized functions dealing with the SEQUENCE OF type.
- * Generally implemented using SET OF.
- */
-#define SEQUENCE_OF_free SET_OF_free
-#define SEQUENCE_OF_print SET_OF_print
-#define SEQUENCE_OF_constraint SET_OF_constraint
-#define SEQUENCE_OF_decode_ber SET_OF_decode_ber
-#define SEQUENCE_OF_decode_xer SET_OF_decode_xer
-#define SEQUENCE_OF_decode_uper SET_OF_decode_uper
-der_type_encoder_f SEQUENCE_OF_encode_der;
-xer_type_encoder_f SEQUENCE_OF_encode_xer;
-per_type_encoder_f SEQUENCE_OF_encode_uper;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _CONSTR_SET_OF_H_ */
+++ /dev/null
-/*-
- * Copyright (c) 2003, 2004, 2005 Lev Walkin <vlm@lionet.info>.
- * All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-#include <asn_internal.h>
-#include <constr_SET_OF.h>
-#include <asn_SET_OF.h>
-
-/*
- * Number of bytes left for this structure.
- * (ctx->left) indicates the number of bytes _transferred_ for the structure.
- * (size) contains the number of bytes in the buffer passed.
- */
-#define LEFT ((size<(size_t)ctx->left)?size:(size_t)ctx->left)
-
-/*
- * If the subprocessor function returns with an indication that it wants
- * more data, it may well be a fatal decoding problem, because the
- * size is constrained by the <TLV>'s L, even if the buffer size allows
- * reading more data.
- * For example, consider the buffer containing the following TLVs:
- * <T:5><L:1><V> <T:6>...
- * The TLV length clearly indicates that one byte is expected in V, but
- * if the V processor returns with "want more data" even if the buffer
- * contains way more data than the V processor have seen.
- */
-#define SIZE_VIOLATION (ctx->left >= 0 && (size_t)ctx->left <= size)
-
-/*
- * This macro "eats" the part of the buffer which is definitely "consumed",
- * i.e. was correctly converted into local representation or rightfully skipped.
- */
-#undef ADVANCE
-#define ADVANCE(num_bytes) do { \
- size_t num = num_bytes; \
- ptr = ((const char *)ptr) + num;\
- size -= num; \
- if(ctx->left >= 0) \
- ctx->left -= num; \
- consumed_myself += num; \
- } while(0)
-
-/*
- * Switch to the next phase of parsing.
- */
-#undef NEXT_PHASE
-#undef PHASE_OUT
-#define NEXT_PHASE(ctx) do { \
- ctx->phase++; \
- ctx->step = 0; \
- } while(0)
-#define PHASE_OUT(ctx) do { ctx->phase = 10; } while(0)
-
-/*
- * Return a standardized complex structure.
- */
-#undef RETURN
-#define RETURN(_code) do { \
- rval.code = _code; \
- rval.consumed = consumed_myself;\
- return rval; \
- } while(0)
-
-/*
- * The decoder of the SET OF type.
- */
-asn_dec_rval_t
-SET_OF_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
- void **struct_ptr, const void *ptr, size_t size, int tag_mode) {
- /*
- * Bring closer parts of structure description.
- */
- asn_SET_OF_specifics_t *specs = (asn_SET_OF_specifics_t *)td->specifics;
- asn_TYPE_member_t *elm = td->elements; /* Single one */
-
- /*
- * Parts of the structure being constructed.
- */
- void *st = *struct_ptr; /* Target structure. */
- asn_struct_ctx_t *ctx; /* Decoder context */
-
- ber_tlv_tag_t tlv_tag; /* T from TLV */
- asn_dec_rval_t rval; /* Return code from subparsers */
-
- ssize_t consumed_myself = 0; /* Consumed bytes from ptr */
-
- ASN_DEBUG("Decoding %s as SET OF", td->name);
-
- /*
- * Create the target structure if it is not present already.
- */
- if(st == 0) {
- st = *struct_ptr = CALLOC(1, specs->struct_size);
- if(st == 0) {
- RETURN(RC_FAIL);
- }
- }
-
- /*
- * Restore parsing context.
- */
- ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset);
-
- /*
- * Start to parse where left previously
- */
- switch(ctx->phase) {
- case 0:
- /*
- * PHASE 0.
- * Check that the set of tags associated with given structure
- * perfectly fits our expectations.
- */
-
- rval = ber_check_tags(opt_codec_ctx, td, ctx, ptr, size,
- tag_mode, 1, &ctx->left, 0);
- if(rval.code != RC_OK) {
- ASN_DEBUG("%s tagging check failed: %d",
- td->name, rval.code);
- return rval;
- }
-
- if(ctx->left >= 0)
- ctx->left += rval.consumed; /* ?Substracted below! */
- ADVANCE(rval.consumed);
-
- ASN_DEBUG("Structure consumes %ld bytes, "
- "buffer %ld", (long)ctx->left, (long)size);
-
- NEXT_PHASE(ctx);
- /* Fall through */
- case 1:
- /*
- * PHASE 1.
- * From the place where we've left it previously,
- * try to decode the next item.
- */
- for(;; ctx->step = 0) {
- ssize_t tag_len; /* Length of TLV's T */
-
- if(ctx->step & 1)
- goto microphase2;
-
- /*
- * MICROPHASE 1: Synchronize decoding.
- */
-
- if(ctx->left == 0) {
- ASN_DEBUG("End of SET OF %s", td->name);
- /*
- * No more things to decode.
- * Exit out of here.
- */
- PHASE_OUT(ctx);
- RETURN(RC_OK);
- }
-
- /*
- * Fetch the T from TLV.
- */
- tag_len = ber_fetch_tag(ptr, LEFT, &tlv_tag);
- switch(tag_len) {
- case 0: if(!SIZE_VIOLATION) RETURN(RC_WMORE);
- /* Fall through */
- case -1: RETURN(RC_FAIL);
- }
-
- if(ctx->left < 0 && ((const uint8_t *)ptr)[0] == 0) {
- if(LEFT < 2) {
- if(SIZE_VIOLATION)
- RETURN(RC_FAIL);
- else
- RETURN(RC_WMORE);
- } else if(((const uint8_t *)ptr)[1] == 0) {
- /*
- * Found the terminator of the
- * indefinite length structure.
- */
- break;
- }
- }
-
- /* Outmost tag may be unknown and cannot be fetched/compared */
- if(elm->tag != (ber_tlv_tag_t)-1) {
- if(BER_TAGS_EQUAL(tlv_tag, elm->tag)) {
- /*
- * The new list member of expected type has arrived.
- */
- } else {
- ASN_DEBUG("Unexpected tag %s fixed SET OF %s",
- ber_tlv_tag_string(tlv_tag), td->name);
- ASN_DEBUG("%s SET OF has tag %s",
- td->name, ber_tlv_tag_string(elm->tag));
- RETURN(RC_FAIL);
- }
- }
-
- /*
- * MICROPHASE 2: Invoke the member-specific decoder.
- */
- ctx->step |= 1; /* Confirm entering next microphase */
- microphase2:
-
- /*
- * Invoke the member fetch routine according to member's type
- */
- rval = elm->type->ber_decoder(opt_codec_ctx,
- elm->type, &ctx->ptr, ptr, LEFT, 0);
- ASN_DEBUG("In %s SET OF %s code %d consumed %d",
- td->name, elm->type->name,
- rval.code, (int)rval.consumed);
- switch(rval.code) {
- case RC_OK:
- {
- asn_anonymous_set_ *list = _A_SET_FROM_VOID(st);
- if(ASN_SET_ADD(list, ctx->ptr) != 0)
- RETURN(RC_FAIL);
- else
- ctx->ptr = 0;
- }
- break;
- case RC_WMORE: /* More data expected */
- if(!SIZE_VIOLATION) {
- ADVANCE(rval.consumed);
- RETURN(RC_WMORE);
- }
- /* Fall through */
- case RC_FAIL: /* Fatal error */
- RETURN(RC_FAIL);
- } /* switch(rval) */
-
- ADVANCE(rval.consumed);
- } /* for(all list members) */
-
- NEXT_PHASE(ctx);
- case 2:
- /*
- * Read in all "end of content" TLVs.
- */
- while(ctx->left < 0) {
- if(LEFT < 2) {
- if(LEFT > 0 && ((const char *)ptr)[0] != 0) {
- /* Unexpected tag */
- RETURN(RC_FAIL);
- } else {
- RETURN(RC_WMORE);
- }
- }
- if(((const char *)ptr)[0] == 0
- && ((const char *)ptr)[1] == 0) {
- ADVANCE(2);
- ctx->left++;
- } else {
- RETURN(RC_FAIL);
- }
- }
-
- PHASE_OUT(ctx);
- }
-
- RETURN(RC_OK);
-}
-
-/*
- * Internally visible buffer holding a single encoded element.
- */
-struct _el_buffer {
- uint8_t *buf;
- size_t length;
- size_t size;
-};
-/* Append bytes to the above structure */
-static int _el_addbytes(const void *buffer, size_t size, void *el_buf_ptr) {
- struct _el_buffer *el_buf = (struct _el_buffer *)el_buf_ptr;
-
- if(el_buf->length + size > el_buf->size)
- return -1;
-
- memcpy(el_buf->buf + el_buf->length, buffer, size);
-
- el_buf->length += size;
- return 0;
-}
-static int _el_buf_cmp(const void *ap, const void *bp) {
- const struct _el_buffer *a = (const struct _el_buffer *)ap;
- const struct _el_buffer *b = (const struct _el_buffer *)bp;
- int ret;
- size_t common_len;
-
- if(a->length < b->length)
- common_len = a->length;
- else
- common_len = b->length;
-
- ret = memcmp(a->buf, b->buf, common_len);
- if(ret == 0) {
- if(a->length < b->length)
- ret = -1;
- else if(a->length > b->length)
- ret = 1;
- }
-
- return ret;
-}
-
-/*
- * The DER encoder of the SET OF type.
- */
-asn_enc_rval_t
-SET_OF_encode_der(asn_TYPE_descriptor_t *td, void *ptr,
- int tag_mode, ber_tlv_tag_t tag,
- asn_app_consume_bytes_f *cb, void *app_key) {
- asn_TYPE_member_t *elm = td->elements;
- asn_TYPE_descriptor_t *elm_type = elm->type;
- der_type_encoder_f *der_encoder = elm_type->der_encoder;
- asn_anonymous_set_ *list = _A_SET_FROM_VOID(ptr);
- size_t computed_size = 0;
- ssize_t encoding_size = 0;
- struct _el_buffer *encoded_els;
- ssize_t eels_count = 0;
- size_t max_encoded_len = 1;
- asn_enc_rval_t erval;
- int ret;
- int edx;
-
- ASN_DEBUG("Estimating size for SET OF %s", td->name);
-
- /*
- * Gather the length of the underlying members sequence.
- */
- for(edx = 0; edx < list->count; edx++) {
- void *memb_ptr = list->array[edx];
- if(!memb_ptr) continue;
- erval = der_encoder(elm_type, memb_ptr, 0, elm->tag, 0, 0);
- if(erval.encoded == -1)
- return erval;
- computed_size += erval.encoded;
-
- /* Compute maximum encoding's size */
- if(max_encoded_len < (size_t)erval.encoded)
- max_encoded_len = erval.encoded;
- }
-
- /*
- * Encode the TLV for the sequence itself.
- */
- encoding_size = der_write_tags(td, computed_size, tag_mode, 1, tag,
- cb, app_key);
- if(encoding_size == -1) {
- erval.encoded = -1;
- erval.failed_type = td;
- erval.structure_ptr = ptr;
- return erval;
- }
- computed_size += encoding_size;
-
- if(!cb || list->count == 0) {
- erval.encoded = computed_size;
- _ASN_ENCODED_OK(erval);
- }
-
- /*
- * DER mandates dynamic sorting of the SET OF elements
- * according to their encodings. Build an array of the
- * encoded elements.
- */
- encoded_els = (struct _el_buffer *)MALLOC(
- list->count * sizeof(encoded_els[0]));
- if(encoded_els == NULL) {
- erval.encoded = -1;
- erval.failed_type = td;
- erval.structure_ptr = ptr;
- return erval;
- }
-
- ASN_DEBUG("Encoding members of %s SET OF", td->name);
-
- /*
- * Encode all members.
- */
- for(edx = 0; edx < list->count; edx++) {
- void *memb_ptr = list->array[edx];
- struct _el_buffer *encoded_el = &encoded_els[eels_count];
-
- if(!memb_ptr) continue;
-
- /*
- * Prepare space for encoding.
- */
- encoded_el->buf = (uint8_t *)MALLOC(max_encoded_len);
- if(encoded_el->buf) {
- encoded_el->length = 0;
- encoded_el->size = max_encoded_len;
- } else {
- for(edx--; edx >= 0; edx--)
- FREEMEM(encoded_els[edx].buf);
- FREEMEM(encoded_els);
- erval.encoded = -1;
- erval.failed_type = td;
- erval.structure_ptr = ptr;
- return erval;
- }
-
- /*
- * Encode the member into the prepared space.
- */
- erval = der_encoder(elm_type, memb_ptr, 0, elm->tag,
- _el_addbytes, encoded_el);
- if(erval.encoded == -1) {
- for(; edx >= 0; edx--)
- FREEMEM(encoded_els[edx].buf);
- FREEMEM(encoded_els);
- return erval;
- }
- encoding_size += erval.encoded;
- eels_count++;
- }
-
- /*
- * Sort the encoded elements according to their encoding.
- */
- qsort(encoded_els, eels_count, sizeof(encoded_els[0]), _el_buf_cmp);
-
- /*
- * Report encoded elements to the application.
- * Dispose of temporary sorted members table.
- */
- ret = 0;
- for(edx = 0; edx < eels_count; edx++) {
- struct _el_buffer *encoded_el = &encoded_els[edx];
- /* Report encoded chunks to the application */
- if(ret == 0
- && cb(encoded_el->buf, encoded_el->length, app_key) < 0)
- ret = -1;
- FREEMEM(encoded_el->buf);
- }
- FREEMEM(encoded_els);
-
- if(ret || computed_size != (size_t)encoding_size) {
- /*
- * Standard callback failed, or
- * encoded size is not equal to the computed size.
- */
- erval.encoded = -1;
- erval.failed_type = td;
- erval.structure_ptr = ptr;
- } else {
- erval.encoded = computed_size;
- }
-
- _ASN_ENCODED_OK(erval);
-}
-
-#undef XER_ADVANCE
-#define XER_ADVANCE(num_bytes) do { \
- size_t num = num_bytes; \
- buf_ptr = ((const char *)buf_ptr) + num;\
- size -= num; \
- consumed_myself += num; \
- } while(0)
-
-/*
- * Decode the XER (XML) data.
- */
-asn_dec_rval_t
-SET_OF_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
- void **struct_ptr, const char *opt_mname,
- const void *buf_ptr, size_t size) {
- /*
- * Bring closer parts of structure description.
- */
- asn_SET_OF_specifics_t *specs = (asn_SET_OF_specifics_t *)td->specifics;
- asn_TYPE_member_t *element = td->elements;
- const char *elm_tag;
- const char *xml_tag = opt_mname ? opt_mname : td->xml_tag;
-
- /*
- * ... and parts of the structure being constructed.
- */
- void *st = *struct_ptr; /* Target structure. */
- asn_struct_ctx_t *ctx; /* Decoder context */
-
- asn_dec_rval_t rval; /* Return value from a decoder */
- ssize_t consumed_myself = 0; /* Consumed bytes from ptr */
-
- /*
- * Create the target structure if it is not present already.
- */
- if(st == 0) {
- st = *struct_ptr = CALLOC(1, specs->struct_size);
- if(st == 0) RETURN(RC_FAIL);
- }
-
- /* Which tag is expected for the downstream */
- if(specs->as_XMLValueList) {
- elm_tag = (specs->as_XMLValueList == 1) ? 0 : "";
- } else {
- elm_tag = (*element->name)
- ? element->name : element->type->xml_tag;
- }
-
- /*
- * Restore parsing context.
- */
- ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset);
-
- /*
- * Phases of XER/XML processing:
- * Phase 0: Check that the opening tag matches our expectations.
- * Phase 1: Processing body and reacting on closing tag.
- * Phase 2: Processing inner type.
- */
- for(; ctx->phase <= 2;) {
- pxer_chunk_type_e ch_type; /* XER chunk type */
- ssize_t ch_size; /* Chunk size */
- xer_check_tag_e tcv; /* Tag check value */
-
- /*
- * Go inside the inner member of a set.
- */
- if(ctx->phase == 2) {
- asn_dec_rval_t tmprval;
-
- /* Invoke the inner type decoder, m.b. multiple times */
- ASN_DEBUG("XER/SET OF element [%s]", elm_tag);
- tmprval = element->type->xer_decoder(opt_codec_ctx,
- element->type, &ctx->ptr, elm_tag,
- buf_ptr, size);
- if(tmprval.code == RC_OK) {
- asn_anonymous_set_ *list = _A_SET_FROM_VOID(st);
- if(ASN_SET_ADD(list, ctx->ptr) != 0)
- RETURN(RC_FAIL);
- ctx->ptr = 0;
- XER_ADVANCE(tmprval.consumed);
- } else {
- XER_ADVANCE(tmprval.consumed);
- RETURN(tmprval.code);
- }
- ctx->phase = 1; /* Back to body processing */
- ASN_DEBUG("XER/SET OF phase => %d", ctx->phase);
- /* Fall through */
- }
-
- /*
- * Get the next part of the XML stream.
- */
- ch_size = xer_next_token(&ctx->context,
- buf_ptr, size, &ch_type);
- switch(ch_size) {
- case -1: RETURN(RC_FAIL);
- case 0: RETURN(RC_WMORE);
- default:
- switch(ch_type) {
- case PXER_COMMENT: /* Got XML comment */
- case PXER_TEXT: /* Ignore free-standing text */
- XER_ADVANCE(ch_size); /* Skip silently */
- continue;
- case PXER_TAG:
- break; /* Check the rest down there */
- }
- }
-
- tcv = xer_check_tag(buf_ptr, ch_size, xml_tag);
- ASN_DEBUG("XER/SET OF: tcv = %d, ph=%d t=%s",
- tcv, ctx->phase, xml_tag);
- switch(tcv) {
- case XCT_CLOSING:
- if(ctx->phase == 0) break;
- ctx->phase = 0;
- /* Fall through */
- case XCT_BOTH:
- if(ctx->phase == 0) {
- /* No more things to decode */
- XER_ADVANCE(ch_size);
- ctx->phase = 3; /* Phase out */
- RETURN(RC_OK);
- }
- /* Fall through */
- case XCT_OPENING:
- if(ctx->phase == 0) {
- XER_ADVANCE(ch_size);
- ctx->phase = 1; /* Processing body phase */
- continue;
- }
- /* Fall through */
- case XCT_UNKNOWN_OP:
- case XCT_UNKNOWN_BO:
-
- ASN_DEBUG("XER/SET OF: tcv=%d, ph=%d", tcv, ctx->phase);
- if(ctx->phase == 1) {
- /*
- * Process a single possible member.
- */
- ctx->phase = 2;
- continue;
- }
- /* Fall through */
- default:
- break;
- }
-
- ASN_DEBUG("Unexpected XML tag in SET OF");
- break;
- }
-
- ctx->phase = 3; /* "Phase out" on hard failure */
- RETURN(RC_FAIL);
-}
-
-
-
-typedef struct xer_tmp_enc_s {
- void *buffer;
- size_t offset;
- size_t size;
-} xer_tmp_enc_t;
-static int
-SET_OF_encode_xer_callback(const void *buffer, size_t size, void *key) {
- xer_tmp_enc_t *t = (xer_tmp_enc_t *)key;
- if(t->offset + size >= t->size) {
- size_t newsize = (t->size << 2) + size;
- void *p = REALLOC(t->buffer, newsize);
- if(!p) return -1;
- t->buffer = p;
- t->size = newsize;
- }
- memcpy((char *)t->buffer + t->offset, buffer, size);
- t->offset += size;
- return 0;
-}
-static int
-SET_OF_xer_order(const void *aptr, const void *bptr) {
- const xer_tmp_enc_t *a = (const xer_tmp_enc_t *)aptr;
- const xer_tmp_enc_t *b = (const xer_tmp_enc_t *)bptr;
- size_t minlen = a->offset;
- int ret;
- if(b->offset < minlen) minlen = b->offset;
- /* Well-formed UTF-8 has this nice lexicographical property... */
- ret = memcmp(a->buffer, b->buffer, minlen);
- if(ret != 0) return ret;
- if(a->offset == b->offset)
- return 0;
- if(a->offset == minlen)
- return -1;
- return 1;
-}
-
-
-asn_enc_rval_t
-SET_OF_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
- int ilevel, enum xer_encoder_flags_e flags,
- asn_app_consume_bytes_f *cb, void *app_key) {
- asn_enc_rval_t er;
- asn_SET_OF_specifics_t *specs = (asn_SET_OF_specifics_t *)td->specifics;
- asn_TYPE_member_t *elm = td->elements;
- asn_anonymous_set_ *list = _A_SET_FROM_VOID(sptr);
- const char *mname = specs->as_XMLValueList
- ? 0 : ((*elm->name) ? elm->name : elm->type->xml_tag);
- size_t mlen = mname ? strlen(mname) : 0;
- int xcan = (flags & XER_F_CANONICAL);
- xer_tmp_enc_t *encs = 0;
- size_t encs_count = 0;
- void *original_app_key = app_key;
- asn_app_consume_bytes_f *original_cb = cb;
- int i;
-
- if(!sptr) _ASN_ENCODE_FAILED;
-
- if(xcan) {
- encs = (xer_tmp_enc_t *)MALLOC(list->count * sizeof(encs[0]));
- if(!encs) _ASN_ENCODE_FAILED;
- cb = SET_OF_encode_xer_callback;
- }
-
- er.encoded = 0;
-
- for(i = 0; i < list->count; i++) {
- asn_enc_rval_t tmper;
-
- void *memb_ptr = list->array[i];
- if(!memb_ptr) continue;
-
- if(encs) {
- memset(&encs[encs_count], 0, sizeof(encs[0]));
- app_key = &encs[encs_count];
- encs_count++;
- }
-
- if(mname) {
- if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel);
- _ASN_CALLBACK3("<", 1, mname, mlen, ">", 1);
- }
-
- if(!xcan && specs->as_XMLValueList == 1)
- _i_ASN_TEXT_INDENT(1, ilevel + 1);
- tmper = elm->type->xer_encoder(elm->type, memb_ptr,
- ilevel + (specs->as_XMLValueList != 2),
- flags, cb, app_key);
- if(tmper.encoded == -1) {
- td = tmper.failed_type;
- sptr = tmper.structure_ptr;
- goto cb_failed;
- }
- if(tmper.encoded == 0 && specs->as_XMLValueList) {
- const char *name = elm->type->xml_tag;
- size_t len = strlen(name);
- _ASN_CALLBACK3("<", 1, name, len, "/>", 2);
- }
-
- if(mname) {
- _ASN_CALLBACK3("</", 2, mname, mlen, ">", 1);
- er.encoded += 5;
- }
-
- er.encoded += (2 * mlen) + tmper.encoded;
- }
-
- if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel - 1);
-
- if(encs) {
- xer_tmp_enc_t *enc = encs;
- xer_tmp_enc_t *end = encs + encs_count;
- ssize_t control_size = 0;
-
- cb = original_cb;
- app_key = original_app_key;
- qsort(encs, encs_count, sizeof(encs[0]), SET_OF_xer_order);
-
- for(; enc < end; enc++) {
- _ASN_CALLBACK(enc->buffer, enc->offset);
- FREEMEM(enc->buffer);
- enc->buffer = 0;
- control_size += enc->offset;
- }
- assert(control_size == er.encoded);
- }
-
- goto cleanup;
-cb_failed:
- er.encoded = -1;
- er.failed_type = td;
- er.structure_ptr = sptr;
-cleanup:
- if(encs) {
- while(encs_count-- > 0) {
- if(encs[encs_count].buffer)
- FREEMEM(encs[encs_count].buffer);
- }
- FREEMEM(encs);
- }
- _ASN_ENCODED_OK(er);
-}
-
-int
-SET_OF_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
- asn_app_consume_bytes_f *cb, void *app_key) {
- asn_TYPE_member_t *elm = td->elements;
- const asn_anonymous_set_ *list = _A_CSET_FROM_VOID(sptr);
- int ret;
- int i;
-
- if(!sptr) return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
-
- /* Dump preamble */
- if(cb(td->name, strlen(td->name), app_key) < 0
- || cb(" ::= {", 6, app_key) < 0)
- return -1;
-
- for(i = 0; i < list->count; i++) {
- const void *memb_ptr = list->array[i];
- if(!memb_ptr) continue;
-
- _i_INDENT(1);
-
- ret = elm->type->print_struct(elm->type, memb_ptr,
- ilevel + 1, cb, app_key);
- if(ret) return ret;
- }
-
- ilevel--;
- _i_INDENT(1);
-
- return (cb("}", 1, app_key) < 0) ? -1 : 0;
-}
-
-void
-SET_OF_free(asn_TYPE_descriptor_t *td, void *ptr, int contents_only) {
- if(td && ptr) {
- asn_TYPE_member_t *elm = td->elements;
- asn_anonymous_set_ *list = _A_SET_FROM_VOID(ptr);
- int i;
-
- /*
- * Could not use set_of_empty() because of (*free)
- * incompatibility.
- */
- for(i = 0; i < list->count; i++) {
- void *memb_ptr = list->array[i];
- if(memb_ptr)
- ASN_STRUCT_FREE(*elm->type, memb_ptr);
- }
- list->count = 0; /* No meaningful elements left */
-
- asn_set_empty(list); /* Remove (list->array) */
-
- if(!contents_only) {
- FREEMEM(ptr);
- }
- }
-}
-
-int
-SET_OF_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
- asn_app_constraint_failed_f *ctfailcb, void *app_key) {
- asn_TYPE_member_t *elm = td->elements;
- asn_constr_check_f *constr;
- const asn_anonymous_set_ *list = _A_CSET_FROM_VOID(sptr);
- int i;
-
- if(!sptr) {
- _ASN_CTFAIL(app_key, td,
- "%s: value not given (%s:%d)",
- td->name, __FILE__, __LINE__);
- return -1;
- }
-
- constr = elm->memb_constraints;
- if(!constr) constr = elm->type->check_constraints;
-
- /*
- * Iterate over the members of an array.
- * Validate each in turn, until one fails.
- */
- for(i = 0; i < list->count; i++) {
- const void *memb_ptr = list->array[i];
- int ret;
-
- if(!memb_ptr) continue;
-
- ret = constr(elm->type, memb_ptr, ctfailcb, app_key);
- if(ret) return ret;
- }
-
- /*
- * Cannot inherit it eralier:
- * need to make sure we get the updated version.
- */
- if(!elm->memb_constraints)
- elm->memb_constraints = elm->type->check_constraints;
-
- return 0;
-}
-
-asn_dec_rval_t
-SET_OF_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
- asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
- asn_dec_rval_t rv;
- asn_SET_OF_specifics_t *specs = (asn_SET_OF_specifics_t *)td->specifics;
- asn_TYPE_member_t *elm = td->elements; /* Single one */
- void *st = *sptr;
- asn_anonymous_set_ *list;
- asn_per_constraint_t *ct;
- int repeat = 0;
- ssize_t nelems;
-
- if(_ASN_STACK_OVERFLOW_CHECK(opt_codec_ctx))
- _ASN_DECODE_FAILED;
-
- /*
- * Create the target structure if it is not present already.
- */
- if(!st) {
- st = *sptr = CALLOC(1, specs->struct_size);
- if(!st) _ASN_DECODE_FAILED;
- }
- list = _A_SET_FROM_VOID(st);
-
- /* Figure out which constraints to use */
- if(constraints) ct = &constraints->size;
- else if(td->per_constraints) ct = &td->per_constraints->size;
- else ct = 0;
-
- if(ct && ct->flags & APC_EXTENSIBLE) {
- int value = per_get_few_bits(pd, 1);
- if(value < 0) _ASN_DECODE_STARVED;
- if(value) ct = 0; /* Not restricted! */
- }
-
- if(ct && ct->effective_bits >= 0) {
- /* X.691, #19.5: No length determinant */
- nelems = per_get_few_bits(pd, ct->effective_bits);
- ASN_DEBUG("Preparing to fetch %ld+%ld elements from %s",
- (long)nelems, ct->lower_bound, td->name);
- if(nelems < 0) _ASN_DECODE_STARVED;
- nelems += ct->lower_bound;
- } else {
- nelems = -1;
- }
-
- do {
- int i;
- if(nelems < 0) {
- nelems = uper_get_length(pd,
- ct ? ct->effective_bits : -1, &repeat);
- ASN_DEBUG("Got to decode %d elements (eff %d)",
- (int)nelems, (int)ct ? ct->effective_bits : -1);
- if(nelems < 0) _ASN_DECODE_STARVED;
- }
-
- for(i = 0; i < nelems; i++) {
- void *ptr = 0;
- ASN_DEBUG("SET OF %s decoding", elm->type->name);
- rv = elm->type->uper_decoder(opt_codec_ctx, elm->type,
- elm->per_constraints, &ptr, pd);
- ASN_DEBUG("%s SET OF %s decoded %d, %p",
- td->name, elm->type->name, rv.code, ptr);
- if(rv.code == RC_OK) {
- if(ASN_SET_ADD(list, ptr) == 0)
- continue;
- ASN_DEBUG("Failed to add element into %s",
- td->name);
- /* Fall through */
- rv.code == RC_FAIL;
- } else {
- ASN_DEBUG("Failed decoding %s of %s (SET OF)",
- elm->type->name, td->name);
- }
- if(ptr) ASN_STRUCT_FREE(*elm->type, ptr);
- return rv;
- }
-
- nelems = -1; /* Allow uper_get_length() */
- } while(repeat);
-
- ASN_DEBUG("Decoded %s as SET OF", td->name);
-
- rv.code = RC_OK;
- rv.consumed = 0;
- return rv;
-}
-
+++ /dev/null
-/*-
- * Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-#ifndef _CONSTR_SET_OF_H_
-#define _CONSTR_SET_OF_H_
-
-#include <asn_application.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct asn_SET_OF_specifics_s {
- /*
- * Target structure description.
- */
- int struct_size; /* Size of the target structure. */
- int ctx_offset; /* Offset of the asn_struct_ctx_t member */
-
- /* XER-specific stuff */
- int as_XMLValueList; /* The member type must be encoded like this */
-} asn_SET_OF_specifics_t;
-
-/*
- * A set specialized functions dealing with the SET OF type.
- */
-asn_struct_free_f SET_OF_free;
-asn_struct_print_f SET_OF_print;
-asn_constr_check_f SET_OF_constraint;
-ber_type_decoder_f SET_OF_decode_ber;
-der_type_encoder_f SET_OF_encode_der;
-xer_type_decoder_f SET_OF_decode_xer;
-xer_type_encoder_f SET_OF_encode_xer;
-per_type_decoder_f SET_OF_decode_uper;
-per_type_encoder_f SET_OF_encode_uper;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _CONSTR_SET_OF_H_ */
+++ /dev/null
-/*-
- * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-#include <asn_internal.h>
-#include <constr_TYPE.h>
-#include <errno.h>
-
-/*
- * Version of the ASN.1 infrastructure shipped with compiler.
- */
-int get_asn1c_environment_version() { return ASN1C_ENVIRONMENT_VERSION; }
-
-static asn_app_consume_bytes_f _print2fp;
-
-/*
- * Return the outmost tag of the type.
- */
-ber_tlv_tag_t
-asn_TYPE_outmost_tag(asn_TYPE_descriptor_t *type_descriptor,
- const void *struct_ptr, int tag_mode, ber_tlv_tag_t tag) {
-
- if(tag_mode)
- return tag;
-
- if(type_descriptor->tags_count)
- return type_descriptor->tags[0];
-
- return type_descriptor->outmost_tag(type_descriptor, struct_ptr, 0, 0);
-}
-
-/*
- * Print the target language's structure in human readable form.
- */
-int
-asn_fprint(FILE *stream, asn_TYPE_descriptor_t *td, const void *struct_ptr) {
- if(!stream) stream = stdout;
- if(!td || !struct_ptr) {
- errno = EINVAL;
- return -1;
- }
-
- /* Invoke type-specific printer */
- if(td->print_struct(td, struct_ptr, 1, _print2fp, stream))
- return -1;
-
- /* Terminate the output */
- if(_print2fp("\n", 1, stream))
- return -1;
-
- return fflush(stream);
-}
-
-/* Dump the data into the specified stdio stream */
-static int
-_print2fp(const void *buffer, size_t size, void *app_key) {
- FILE *stream = (FILE *)app_key;
-
- if(fwrite(buffer, 1, size, stream) != size)
- return -1;
-
- return 0;
-}
-
-
-/*
- * Some compilers do not support variable args macros.
- * This function is a replacement of ASN_DEBUG() macro.
- */
-void ASN_DEBUG_f(const char *fmt, ...);
-void ASN_DEBUG_f(const char *fmt, ...) {
- va_list ap;
- va_start(ap, fmt);
- vfprintf(stderr, fmt, ap);
- fprintf(stderr, "\n");
- va_end(ap);
-}
+++ /dev/null
-/*-
- * Copyright (c) 2003, 2004, 2005, 2006 Lev Walkin <vlm@lionet.info>.
- * All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-/*
- * This file contains the declaration structure called "ASN.1 Type Definition",
- * which holds all information necessary for encoding and decoding routines.
- * This structure even contains pointer to these encoding and decoding routines
- * for each defined ASN.1 type.
- */
-#ifndef _CONSTR_TYPE_H_
-#define _CONSTR_TYPE_H_
-
-#include <ber_tlv_length.h>
-#include <ber_tlv_tag.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct asn_TYPE_descriptor_s; /* Forward declaration */
-struct asn_TYPE_member_s; /* Forward declaration */
-
-/*
- * This type provides the context information for various ASN.1 routines,
- * primarily ones doing decoding. A member _asn_ctx of this type must be
- * included into certain target language's structures, such as compound types.
- */
-typedef struct asn_struct_ctx_s {
- short phase; /* Decoding phase */
- short step; /* Elementary step of a phase */
- int context; /* Other context information */
- void *ptr; /* Decoder-specific stuff (stack elements) */
- ber_tlv_len_t left; /* Number of bytes left, -1 for indefinite */
-} asn_struct_ctx_t;
-
-#include <ber_decoder.h> /* Basic Encoding Rules decoder */
-#include <der_encoder.h> /* Distinguished Encoding Rules encoder */
-#include <xer_decoder.h> /* Decoder of XER (XML, text) */
-#include <xer_encoder.h> /* Encoder into XER (XML, text) */
-#include <per_decoder.h> /* Packet Encoding Rules decoder */
-#include <per_encoder.h> /* Packet Encoding Rules encoder */
-#include <constraints.h> /* Subtype constraints support */
-
-/*
- * Free the structure according to its specification.
- * If (free_contents_only) is set, the wrapper structure itself (struct_ptr)
- * will not be freed. (It may be useful in case the structure is allocated
- * statically or arranged on the stack, yet its elements are allocated
- * dynamically.)
- */
-typedef void (asn_struct_free_f)(
- struct asn_TYPE_descriptor_s *type_descriptor,
- void *struct_ptr, int free_contents_only);
-#define ASN_STRUCT_FREE(asn_DEF, ptr) (asn_DEF).free_struct(&(asn_DEF),ptr,0)
-#define ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF, ptr) \
- (asn_DEF).free_struct(&(asn_DEF),ptr,1)
-
-/*
- * Print the structure according to its specification.
- */
-typedef int (asn_struct_print_f)(
- struct asn_TYPE_descriptor_s *type_descriptor,
- const void *struct_ptr,
- int level, /* Indentation level */
- asn_app_consume_bytes_f *callback, void *app_key);
-
-/*
- * Return the outmost tag of the type.
- * If the type is untagged CHOICE, the dynamic operation is performed.
- * NOTE: This function pointer type is only useful internally.
- * Do not use it in your application.
- */
-typedef ber_tlv_tag_t (asn_outmost_tag_f)(
- struct asn_TYPE_descriptor_s *type_descriptor,
- const void *struct_ptr, int tag_mode, ber_tlv_tag_t tag);
-/* The instance of the above function type; used internally. */
-asn_outmost_tag_f asn_TYPE_outmost_tag;
-
-\f
-/*
- * The definitive description of the destination language's structure.
- */
-typedef struct asn_TYPE_descriptor_s {
- char *name; /* A name of the ASN.1 type. "" in some cases. */
- char *xml_tag; /* Name used in XML tag */
-
- /*
- * Generalized functions for dealing with the specific type.
- * May be directly invoked by applications.
- */
- asn_struct_free_f *free_struct; /* Free the structure */
- asn_struct_print_f *print_struct; /* Human readable output */
- asn_constr_check_f *check_constraints; /* Constraints validator */
- ber_type_decoder_f *ber_decoder; /* Generic BER decoder */
- der_type_encoder_f *der_encoder; /* Canonical DER encoder */
- xer_type_decoder_f *xer_decoder; /* Generic XER decoder */
- xer_type_encoder_f *xer_encoder; /* [Canonical] XER encoder */
- per_type_decoder_f *uper_decoder; /* Unaligned PER decoder */
- per_type_encoder_f *uper_encoder; /* Unaligned PER encoder */
-
- /***********************************************************************
- * Internally useful members. Not to be used by applications directly. *
- **********************************************************************/
-
- /*
- * Tags that are expected to occur.
- */
- asn_outmost_tag_f *outmost_tag; /* <optional, internal> */
- ber_tlv_tag_t *tags; /* Effective tags sequence for this type */
- int tags_count; /* Number of tags which are expected */
- ber_tlv_tag_t *all_tags;/* Every tag for BER/containment */
- int all_tags_count; /* Number of tags */
-
- asn_per_constraints_t *per_constraints; /* PER compiled constraints */
-
- /*
- * An ASN.1 production type members (members of SEQUENCE, SET, CHOICE).
- */
- struct asn_TYPE_member_s *elements;
- int elements_count;
-
- /*
- * Additional information describing the type, used by appropriate
- * functions above.
- */
- void *specifics;
-} asn_TYPE_descriptor_t;
-
-/*
- * This type describes an element of the constructed type,
- * i.e. SEQUENCE, SET, CHOICE, etc.
- */
- enum asn_TYPE_flags_e {
- ATF_NOFLAGS,
- ATF_POINTER = 0x01, /* Represented by the pointer */
- ATF_OPEN_TYPE = 0x02 /* ANY type, without meaningful tag */
- };
-typedef struct asn_TYPE_member_s {
- enum asn_TYPE_flags_e flags; /* Element's presentation flags */
- int optional; /* Following optional members, including current */
- int memb_offset; /* Offset of the element */
- ber_tlv_tag_t tag; /* Outmost (most immediate) tag */
- int tag_mode; /* IMPLICIT/no/EXPLICIT tag at current level */
- asn_TYPE_descriptor_t *type; /* Member type descriptor */
- asn_constr_check_f *memb_constraints; /* Constraints validator */
- asn_per_constraints_t *per_constraints; /* PER compiled constraints */
- int (*default_value)(int setval, void **sptr); /* DEFAULT <value> */
- char *name; /* ASN.1 identifier of the element */
-} asn_TYPE_member_t;
-
-/*
- * BER tag to element number mapping.
- */
-typedef struct asn_TYPE_tag2member_s {
- ber_tlv_tag_t el_tag; /* Outmost tag of the member */
- int el_no; /* Index of the associated member, base 0 */
- int toff_first; /* First occurence of the el_tag, relative */
- int toff_last; /* Last occurence of the el_tag, relatvie */
-} asn_TYPE_tag2member_t;
-
-/*
- * This function is a wrapper around (td)->print_struct, which prints out
- * the contents of the target language's structure (struct_ptr) into the
- * file pointer (stream) in human readable form.
- * RETURN VALUES:
- * 0: The structure is printed.
- * -1: Problem dumping the structure.
- * (See also xer_fprint() in xer_encoder.h)
- */
-int asn_fprint(FILE *stream, /* Destination stream descriptor */
- asn_TYPE_descriptor_t *td, /* ASN.1 type descriptor */
- const void *struct_ptr); /* Structure to be printed */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _CONSTR_TYPE_H_ */
+++ /dev/null
-#include "asn_internal.h"
-#include "constraints.h"
-
-int
-asn_generic_no_constraint(asn_TYPE_descriptor_t *type_descriptor,
- const void *struct_ptr, asn_app_constraint_failed_f *cb, void *key) {
-
- (void)type_descriptor; /* Unused argument */
- (void)struct_ptr; /* Unused argument */
- (void)cb; /* Unused argument */
- (void)key; /* Unused argument */
-
- /* Nothing to check */
- return 0;
-}
-
-int
-asn_generic_unknown_constraint(asn_TYPE_descriptor_t *type_descriptor,
- const void *struct_ptr, asn_app_constraint_failed_f *cb, void *key) {
-
- (void)type_descriptor; /* Unused argument */
- (void)struct_ptr; /* Unused argument */
- (void)cb; /* Unused argument */
- (void)key; /* Unused argument */
-
- /* Unknown how to check */
- return 0;
-}
-
-struct errbufDesc {
- asn_TYPE_descriptor_t *failed_type;
- const void *failed_struct_ptr;
- char *errbuf;
- size_t errlen;
-};
-
-static void
-_asn_i_ctfailcb(void *key, asn_TYPE_descriptor_t *td, const void *sptr, const char *fmt, ...) {
- struct errbufDesc *arg = key;
- va_list ap;
- ssize_t vlen;
- ssize_t maxlen;
-
- arg->failed_type = td;
- arg->failed_struct_ptr = sptr;
-
- maxlen = arg->errlen;
- if(maxlen <= 0)
- return;
-
- va_start(ap, fmt);
- vlen = vsnprintf(arg->errbuf, maxlen, fmt, ap);
- va_end(ap);
- if(vlen >= maxlen) {
- arg->errbuf[maxlen-1] = '\0'; /* Ensuring libc correctness */
- arg->errlen = maxlen - 1; /* Not counting termination */
- return;
- } else if(vlen >= 0) {
- arg->errbuf[vlen] = '\0'; /* Ensuring libc correctness */
- arg->errlen = vlen; /* Not counting termination */
- } else {
- /*
- * The libc on this system is broken.
- */
- vlen = sizeof("<broken vsnprintf>") - 1;
- maxlen--;
- arg->errlen = vlen < maxlen ? vlen : maxlen;
- memcpy(arg->errbuf, "<broken vsnprintf>", arg->errlen);
- arg->errbuf[arg->errlen] = 0;
- }
-
- return;
-}
-
-int
-asn_check_constraints(asn_TYPE_descriptor_t *type_descriptor,
- const void *struct_ptr, char *errbuf, size_t *errlen) {
- struct errbufDesc arg;
- int ret;
-
- arg.failed_type = 0;
- arg.failed_struct_ptr = 0;
- arg.errbuf = errbuf;
- arg.errlen = errlen ? *errlen : 0;
-
- ret = type_descriptor->check_constraints(type_descriptor,
- struct_ptr, _asn_i_ctfailcb, &arg);
- if(ret == -1 && errlen)
- *errlen = arg.errlen;
-
- return ret;
-}
-
+++ /dev/null
-/*-
- * Copyright (c) 2004, 2006 Lev Walkin <vlm@lionet.info>. All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-#ifndef _ASN1_CONSTRAINTS_VALIDATOR_H_
-#define _ASN1_CONSTRAINTS_VALIDATOR_H_
-
-#include <asn_system.h> /* Platform-dependent types */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct asn_TYPE_descriptor_s; /* Forward declaration */
-
-/*
- * Validate the structure according to the ASN.1 constraints.
- * If errbuf and errlen are given, they shall be pointing to the appropriate
- * buffer space and its length before calling this function. Alternatively,
- * they could be passed as NULL's. If constraints validation fails,
- * errlen will contain the actual number of bytes taken from the errbuf
- * to encode an error message (properly 0-terminated).
- *
- * RETURN VALUES:
- * This function returns 0 in case all ASN.1 constraints are met
- * and -1 if one or more constraints were failed.
- */
-int
-asn_check_constraints(struct asn_TYPE_descriptor_s *type_descriptor,
- const void *struct_ptr, /* Target language's structure */
- char *errbuf, /* Returned error description */
- size_t *errlen /* Length of the error description */
- );
-
-
-/*
- * Generic type for constraint checking callback,
- * associated with every type descriptor.
- */
-typedef int (asn_constr_check_f)(
- struct asn_TYPE_descriptor_s *type_descriptor,
- const void *struct_ptr,
- asn_app_constraint_failed_f *optional_callback, /* Log the error */
- void *optional_app_key /* Opaque key passed to a callback */
- );
-
-/*******************************
- * INTERNALLY USEFUL FUNCTIONS *
- *******************************/
-
-asn_constr_check_f asn_generic_no_constraint; /* No constraint whatsoever */
-asn_constr_check_f asn_generic_unknown_constraint; /* Not fully supported */
-
-/*
- * Invoke the callback with a complete error message.
- */
-#define _ASN_CTFAIL if(ctfailcb) ctfailcb
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _ASN1_CONSTRAINTS_VALIDATOR_H_ */
+++ /dev/null
-/*
- * Generic converter template for a selected ASN.1 type.
- * Copyright (c) 2005, 2006 Lev Walkin <vlm@lionet.info>. All rights reserved.
- *
- * To compile with your own ASN.1 type, please redefine the PDU as shown:
- *
- * cc -DPDU=MyCustomType -o myDecoder.o -c converter-sample.c
- */
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <stdio.h>
-#include <sys/types.h>
-#include <stdlib.h> /* for atoi(3) */
-#include <unistd.h> /* for getopt(3) */
-#include <string.h> /* for strerror(3) */
-#include <sysexits.h> /* for EX_* exit codes */
-#include <assert.h> /* for assert(3) */
-#include <errno.h> /* for errno */
-
-#include <asn_application.h>
-#include <asn_internal.h> /* for _ASN_DEFAULT_STACK_MAX */
-
-/* Convert "Type" defined by -DPDU into "asn_DEF_Type" */
-#define ASN_DEF_PDU(t) asn_DEF_ ## t
-#define DEF_PDU_Type(t) ASN_DEF_PDU(t)
-#define PDU_Type DEF_PDU_Type(PDU)
-
-extern asn_TYPE_descriptor_t PDU_Type; /* ASN.1 type to be decoded */
-#ifdef ASN_PDU_COLLECTION /* Generated by asn1c: -pdu=... */
-extern asn_TYPE_descriptor_t *asn_pdu_collection[];
-#endif
-
-/*
- * Open file and parse its contens.
- */
-static void *data_decode_from_file(asn_TYPE_descriptor_t *asnTypeOfPDU,
- FILE *file, const char *name, ssize_t suggested_bufsize, int first_pdu);
-static int write_out(const void *buffer, size_t size, void *key);
-static FILE *argument_to_file(char *av[], int idx);
-static char *argument_to_name(char *av[], int idx);
-
- int opt_debug; /* -d (or -dd) */
-static int opt_check; /* -c (constraints checking) */
-static int opt_stack; /* -s (maximum stack size) */
-static int opt_ippad; /* -per-padded (PER input is byte-padded) */
-static int opt_onepdu; /* -1 (decode single PDU) */
-
-/* Input data format selector */
-static enum input_format {
- INP_BER, /* -iber: BER input */
- INP_XER, /* -ixer: XER input */
- INP_PER /* -iper: Unaligned PER input */
-} iform; /* -i<format> */
-
-/* Output data format selector */
-static enum output_format {
- OUT_XER, /* -oxer: XER (XML) output */
- OUT_DER, /* -oder: DER (BER) output */
- OUT_PER, /* -oper: Unaligned PER output */
- OUT_TEXT, /* -otext: semi-structured text */
- OUT_NULL /* -onull: No pretty-printing */
-} oform; /* -o<format> */
-
-/* Debug output function */
-static inline void
-DEBUG(const char *fmt, ...) {
- va_list ap;
- if(!opt_debug) return;
- fprintf(stderr, "AD: ");
- va_start(ap, fmt);
- vfprintf(stderr, fmt, ap);
- va_end(ap);
- fprintf(stderr, "\n");
-}
-
-int
-main(int ac, char *av[]) {
- static asn_TYPE_descriptor_t *pduType = &PDU_Type;
- ssize_t suggested_bufsize = 8192; /* close or equal to stdio buffer */
- int number_of_iterations = 1;
- int num;
- int ch;
-
- /* Figure out if Unaligned PER needs to be default */
- if(pduType->uper_decoder)
- iform = INP_PER;
-
- /*
- * Pocess the command-line argments.
- */
- while((ch = getopt(ac, av, "i:o:1b:cdn:p:hs:")) != -1)
- switch(ch) {
- case 'i':
- if(optarg[0] == 'b') { iform = INP_BER; break; }
- if(optarg[0] == 'x') { iform = INP_XER; break; }
- if(pduType->uper_decoder
- && optarg[0] == 'p') { iform = INP_PER; break; }
- fprintf(stderr, "-i<format>: '%s': improper format selector\n",
- optarg);
- exit(EX_UNAVAILABLE);
- case 'o':
- if(optarg[0] == 'd') { oform = OUT_DER; break; }
- if(pduType->uper_encoder
- && optarg[0] == 'p') { oform = OUT_PER; break; }
- if(optarg[0] == 'x') { oform = OUT_XER; break; }
- if(optarg[0] == 't') { oform = OUT_TEXT; break; }
- if(optarg[0] == 'n') { oform = OUT_NULL; break; }
- fprintf(stderr, "-o<format>: '%s': improper format selector\n",
- optarg);
- exit(EX_UNAVAILABLE);
- case '1':
- opt_onepdu = 1;
- break;
- case 'b':
- suggested_bufsize = atoi(optarg);
- if(suggested_bufsize < 1
- || suggested_bufsize > 16 * 1024 * 1024) {
- fprintf(stderr,
- "-b %s: Improper buffer size (1..16M)\n",
- optarg);
- exit(EX_UNAVAILABLE);
- }
- break;
- case 'c':
- opt_check = 1;
- break;
- case 'd':
- opt_debug++; /* Double -dd means ASN.1 debug */
- break;
- case 'n':
- number_of_iterations = atoi(optarg);
- if(number_of_iterations < 1) {
- fprintf(stderr,
- "-n %s: Improper iterations count\n", optarg);
- exit(EX_UNAVAILABLE);
- }
- break;
- case 'p':
- if(strcmp(optarg, "er-padded") == 0) {
- opt_ippad = 1;
- break;
- }
-#ifdef ASN_PDU_COLLECTION
- if(strcmp(optarg, "list") == 0) {
- asn_TYPE_descriptor_t **pdu = asn_pdu_collection;
- fprintf(stderr, "Available PDU types:\n");
- for(; *pdu; pdu++) printf("%s\n", (*pdu)->name);
- exit(0);
- } else if(optarg[0] >= 'A' && optarg[0] <= 'Z') {
- asn_TYPE_descriptor_t **pdu = asn_pdu_collection;
- while(*pdu && strcmp((*pdu)->name, optarg)) pdu++;
- if(*pdu) { pduType = *pdu; break; }
- fprintf(stderr, "-p %s: Unrecognized PDU\n", optarg);
- }
-#endif /* ASN_PDU_COLLECTION */
- fprintf(stderr, "-p %s: Unrecognized option\n", optarg);
- exit(EX_UNAVAILABLE);
- case 's':
- opt_stack = atoi(optarg);
- if(opt_stack < 0) {
- fprintf(stderr,
- "-s %s: Non-negative value expected\n",
- optarg);
- exit(EX_UNAVAILABLE);
- }
- break;
- case 'h':
- default:
- fprintf(stderr, "Usage: %s [options] <data.ber> ...\n", av[0]);
- fprintf(stderr, "Where options are:\n");
- if(pduType->uper_decoder)
- fprintf(stderr,
- " -iper Input is in Unaligned PER (Packed Encoding Rules) (DEFAULT)\n");
- fprintf(stderr,
- " -iber Input is in BER (Basic Encoding Rules)%s\n",
- iform == INP_PER ? "" : " (DEFAULT)");
- fprintf(stderr,
- " -ixer Input is in XER (XML Encoding Rules)\n");
- if(pduType->uper_encoder)
- fprintf(stderr,
- " -oper Output in Unaligned PER (Packed Encoding Rules)\n");
- fprintf(stderr,
- " -oder Output in DER (Distinguished Encoding Rules)\n"
- " -oxer Output in XER (XML Encoding Rules) (DEFAULT)\n"
- " -otext Output in plain semi-structured text (dump)\n"
- " -onull Verify (decode) input, but do not output\n");
- if(pduType->uper_decoder)
- fprintf(stderr,
- " -per-padded Assume PER PDUs are byte-padded (-iper)\n");
-#ifdef ASN_PDU_COLLECTION
- fprintf(stderr,
- " -p <PDU> Specify PDU type to decode\n"
- " -p list List available PDUs\n");
-#endif /* ASN_PDU_COLLECTION */
- fprintf(stderr,
- " -1 Decode only the first PDU in file\n"
- " -b <size> Set the i/o buffer size (default is %ld)\n"
- " -c Check ASN.1 constraints after decoding\n"
- " -d Enable debugging (-dd is even better)\n"
- " -n <num> Process files <num> times\n"
- " -s <size> Set the stack usage limit (default is %d)\n"
- , (long)suggested_bufsize, _ASN_DEFAULT_STACK_MAX);
- exit(EX_USAGE);
- }
-
- ac -= optind;
- av += optind;
-
- if(ac < 1) {
- fprintf(stderr, "%s: No input files specified. "
- "Try '-h' for more information\n",
- av[-optind]);
- exit(EX_USAGE);
- }
-
- setvbuf(stdout, 0, _IOLBF, 0);
-
- for(num = 0; num < number_of_iterations; num++) {
- int ac_i;
- /*
- * Process all files in turn.
- */
- for(ac_i = 0; ac_i < ac; ac_i++) {
- asn_enc_rval_t erv;
- void *structure; /* Decoded structure */
- FILE *file = argument_to_file(av, ac_i);
- char *name = argument_to_name(av, ac_i);
- int first_pdu;
-
- for(first_pdu = 1; first_pdu || !opt_onepdu; first_pdu = 0) {
- /*
- * Decode the encoded structure from file.
- */
- structure = data_decode_from_file(pduType,
- file, name, suggested_bufsize, first_pdu);
- if(!structure) {
- if(errno) {
- /* Error message is already printed */
- exit(EX_DATAERR);
- } else {
- /* EOF */
- break;
- }
- }
-
- /* Check ASN.1 constraints */
- if(opt_check) {
- char errbuf[128];
- size_t errlen = sizeof(errbuf);
- if(asn_check_constraints(pduType, structure,
- errbuf, &errlen)) {
- fprintf(stderr, "%s: ASN.1 constraint "
- "check failed: %s\n", name, errbuf);
- exit(EX_DATAERR);
- }
- }
-
- switch(oform) {
- case OUT_NULL:
- fprintf(stderr, "%s: decoded successfully\n", name);
- break;
- case OUT_TEXT: /* -otext */
- asn_fprint(stdout, pduType, structure);
- break;
- case OUT_XER: /* -oxer */
- if(xer_fprint(stdout, pduType, structure)) {
- fprintf(stderr,
- "%s: Cannot convert %s into XML\n",
- name, pduType->name);
- exit(EX_UNAVAILABLE);
- }
- break;
- case OUT_DER:
- erv = der_encode(pduType, structure, write_out, stdout);
- if(erv.encoded < 0) {
- fprintf(stderr,
- "%s: Cannot convert %s into DER\n",
- name, pduType->name);
- exit(EX_UNAVAILABLE);
- }
- DEBUG("Encoded in %ld bytes of DER", (long)erv.encoded);
- break;
- case OUT_PER:
- erv = uper_encode(pduType, structure, write_out, stdout);
- if(erv.encoded < 0) {
- fprintf(stderr,
- "%s: Cannot convert %s into Unaligned PER\n",
- name, pduType->name);
- exit(EX_UNAVAILABLE);
- }
- DEBUG("Encoded in %ld bits of UPER", (long)erv.encoded);
- break;
- }
-
- ASN_STRUCT_FREE(*pduType, structure);
- }
-
- if(file && file != stdin)
- fclose(file);
- }
- }
-
- return 0;
-}
-
-static struct dynamic_buffer {
- uint8_t *data; /* Pointer to the data bytes */
- size_t offset; /* Offset from the start */
- size_t length; /* Length of meaningful contents */
- size_t unbits; /* Unused bits in the last byte */
- size_t allocated; /* Allocated memory for data */
- int nreallocs; /* Number of data reallocations */
- off_t bytes_shifted; /* Number of bytes ever shifted */
-} DynamicBuffer;
-
-static void
-buffer_dump() {
- uint8_t *p = DynamicBuffer.data + DynamicBuffer.offset;
- uint8_t *e = p + DynamicBuffer.length - (DynamicBuffer.unbits ? 1 : 0);
- if(!opt_debug) return;
- DEBUG("Buffer: { d=%p, o=%ld, l=%ld, u=%ld, a=%ld, s=%ld }",
- DynamicBuffer.data,
- (long)DynamicBuffer.offset,
- (long)DynamicBuffer.length,
- (long)DynamicBuffer.unbits,
- (long)DynamicBuffer.allocated,
- (long)DynamicBuffer.bytes_shifted);
- for(; p < e; p++) {
- fprintf(stderr, " %c%c%c%c%c%c%c%c",
- ((*p >> 7) & 1) ? '1' : '0',
- ((*p >> 6) & 1) ? '1' : '0',
- ((*p >> 5) & 1) ? '1' : '0',
- ((*p >> 4) & 1) ? '1' : '0',
- ((*p >> 3) & 1) ? '1' : '0',
- ((*p >> 2) & 1) ? '1' : '0',
- ((*p >> 1) & 1) ? '1' : '0',
- ((*p >> 0) & 1) ? '1' : '0');
- }
- if(DynamicBuffer.unbits) {
- int shift;
- fprintf(stderr, " ");
- for(shift = 7; shift >= DynamicBuffer.unbits; shift--)
- fprintf(stderr, "%c", ((*p >> shift) & 1) ? '1' : '0');
- fprintf(stderr, " %d:%d\n",
- DynamicBuffer.length - 1, 8 - DynamicBuffer.unbits);
- } else {
- fprintf(stderr, " %d\n", DynamicBuffer.length);
- }
-}
-
-/*
- * Move the buffer content left N bits, possibly joining it with
- * preceeding content.
- */
-static void
-buffer_shift_left(size_t offset, int bits) {
- uint8_t *ptr = DynamicBuffer.data + DynamicBuffer.offset + offset;
- uint8_t *end = DynamicBuffer.data + DynamicBuffer.offset
- + DynamicBuffer.length - 1;
-
- if(!bits) return;
-
- DEBUG("Shifting left %d bits off %ld (o=%ld, u=%ld, l=%ld)",
- bits, (long)offset,
- (long)DynamicBuffer.offset,
- (long)DynamicBuffer.unbits,
- (long)DynamicBuffer.length);
-
- if(offset) {
- int right;
- right = ptr[0] >> (8 - bits);
-
- DEBUG("oleft: %c%c%c%c%c%c%c%c",
- ((ptr[-1] >> 7) & 1) ? '1' : '0',
- ((ptr[-1] >> 6) & 1) ? '1' : '0',
- ((ptr[-1] >> 5) & 1) ? '1' : '0',
- ((ptr[-1] >> 4) & 1) ? '1' : '0',
- ((ptr[-1] >> 3) & 1) ? '1' : '0',
- ((ptr[-1] >> 2) & 1) ? '1' : '0',
- ((ptr[-1] >> 1) & 1) ? '1' : '0',
- ((ptr[-1] >> 0) & 1) ? '1' : '0');
-
- DEBUG("oriht: %c%c%c%c%c%c%c%c",
- ((ptr[0] >> 7) & 1) ? '1' : '0',
- ((ptr[0] >> 6) & 1) ? '1' : '0',
- ((ptr[0] >> 5) & 1) ? '1' : '0',
- ((ptr[0] >> 4) & 1) ? '1' : '0',
- ((ptr[0] >> 3) & 1) ? '1' : '0',
- ((ptr[0] >> 2) & 1) ? '1' : '0',
- ((ptr[0] >> 1) & 1) ? '1' : '0',
- ((ptr[0] >> 0) & 1) ? '1' : '0');
-
- DEBUG("mriht: %c%c%c%c%c%c%c%c",
- ((right >> 7) & 1) ? '1' : '0',
- ((right >> 6) & 1) ? '1' : '0',
- ((right >> 5) & 1) ? '1' : '0',
- ((right >> 4) & 1) ? '1' : '0',
- ((right >> 3) & 1) ? '1' : '0',
- ((right >> 2) & 1) ? '1' : '0',
- ((right >> 1) & 1) ? '1' : '0',
- ((right >> 0) & 1) ? '1' : '0');
-
- ptr[-1] = (ptr[-1] & (0xff << bits)) | right;
-
- DEBUG("after: %c%c%c%c%c%c%c%c",
- ((ptr[-1] >> 7) & 1) ? '1' : '0',
- ((ptr[-1] >> 6) & 1) ? '1' : '0',
- ((ptr[-1] >> 5) & 1) ? '1' : '0',
- ((ptr[-1] >> 4) & 1) ? '1' : '0',
- ((ptr[-1] >> 3) & 1) ? '1' : '0',
- ((ptr[-1] >> 2) & 1) ? '1' : '0',
- ((ptr[-1] >> 1) & 1) ? '1' : '0',
- ((ptr[-1] >> 0) & 1) ? '1' : '0');
- }
-
- buffer_dump();
-
- for(; ptr < end; ptr++) {
- int right = ptr[1] >> (8 - bits);
- *ptr = (*ptr << bits) | right;
- }
- *ptr <<= bits;
-
- DEBUG("Unbits [%d=>", (int)DynamicBuffer.unbits);
- if(DynamicBuffer.unbits == 0) {
- DynamicBuffer.unbits += bits;
- } else {
- DynamicBuffer.unbits += bits;
- if(DynamicBuffer.unbits > 7) {
- DynamicBuffer.unbits -= 8;
- DynamicBuffer.length--;
- DynamicBuffer.bytes_shifted++;
- }
- }
- DEBUG("Unbits =>%d]", (int)DynamicBuffer.unbits);
-
- buffer_dump();
-
- DEBUG("Shifted. Now (o=%ld, u=%ld l=%ld)",
- (long)DynamicBuffer.offset,
- (long)DynamicBuffer.unbits,
- (long)DynamicBuffer.length);
-
-
-}
-
-/*
- * Ensure that the buffer contains at least this amount of free space.
- */
-static void add_bytes_to_buffer(const void *data2add, size_t bytes) {
-
- if(bytes == 0) return;
-
- DEBUG("=> add_bytes(%ld) { o=%ld l=%ld u=%ld, s=%ld }",
- (long)bytes,
- (long)DynamicBuffer.offset,
- (long)DynamicBuffer.length,
- (long)DynamicBuffer.unbits,
- (long)DynamicBuffer.allocated);
-
- if(DynamicBuffer.allocated
- >= (DynamicBuffer.offset + DynamicBuffer.length + bytes)) {
- DEBUG("\tNo buffer reallocation is necessary");
- } else if(bytes <= DynamicBuffer.offset) {
- DEBUG("\tContents shifted by %ld", DynamicBuffer.offset);
-
- /* Shift the buffer contents */
- memmove(DynamicBuffer.data,
- DynamicBuffer.data + DynamicBuffer.offset,
- DynamicBuffer.length);
- DynamicBuffer.bytes_shifted += DynamicBuffer.offset;
- DynamicBuffer.offset = 0;
- } else {
- size_t newsize = (DynamicBuffer.allocated << 2) + bytes;
- void *p = MALLOC(newsize);
- if(!p) {
- perror("malloc()");
- exit(EX_OSERR);
- }
- memcpy(p,
- DynamicBuffer.data + DynamicBuffer.offset,
- DynamicBuffer.length);
- FREEMEM(DynamicBuffer.data);
- DynamicBuffer.data = (char *)p;
- DynamicBuffer.offset = 0;
- DynamicBuffer.allocated = newsize;
- DynamicBuffer.nreallocs++;
- DEBUG("\tBuffer reallocated to %ld (%d time)",
- newsize, DynamicBuffer.nreallocs);
- }
-
- memcpy(DynamicBuffer.data
- + DynamicBuffer.offset + DynamicBuffer.length,
- data2add, bytes);
- DynamicBuffer.length += bytes;
- if(DynamicBuffer.unbits) {
- int bits = DynamicBuffer.unbits;
- DynamicBuffer.unbits = 0;
- buffer_shift_left(DynamicBuffer.length - bytes, bits);
- }
-
- DEBUG("<= add_bytes(%ld) { o=%ld l=%ld u=%ld, s=%ld }",
- (long)bytes,
- (long)DynamicBuffer.offset,
- (long)DynamicBuffer.length,
- (long)DynamicBuffer.unbits,
- (long)DynamicBuffer.allocated);
-}
-
-static void *
-data_decode_from_file(asn_TYPE_descriptor_t *pduType, FILE *file, const char *name, ssize_t suggested_bufsize, int on_first_pdu) {
- static uint8_t *fbuf;
- static ssize_t fbuf_size;
- static asn_codec_ctx_t s_codec_ctx;
- asn_codec_ctx_t *opt_codec_ctx = 0;
- void *structure = 0;
- asn_dec_rval_t rval;
- size_t old_offset;
- size_t new_offset;
- int tolerate_eof;
- size_t rd;
-
- if(!file) {
- fprintf(stderr, "%s: %s\n", name, strerror(errno));
- errno = EINVAL;
- return 0;
- }
-
- if(opt_stack) {
- s_codec_ctx.max_stack_size = opt_stack;
- opt_codec_ctx = &s_codec_ctx;
- }
-
- DEBUG("Processing %s", name);
-
- /* prepare the file buffer */
- if(fbuf_size != suggested_bufsize) {
- fbuf = (char *)REALLOC(fbuf, suggested_bufsize);
- if(!fbuf) {
- perror("realloc()");
- exit(EX_OSERR);
- }
- fbuf_size = suggested_bufsize;
- }
-
- if(on_first_pdu) {
- DynamicBuffer.offset = 0;
- DynamicBuffer.length = 0;
- DynamicBuffer.unbits = 0;
- DynamicBuffer.allocated = 0;
- DynamicBuffer.bytes_shifted = 0;
- DynamicBuffer.nreallocs = 0;
- }
-
- old_offset = DynamicBuffer.bytes_shifted + DynamicBuffer.offset;
-
- /* Pretend immediate EOF */
- rval.code = RC_WMORE;
- rval.consumed = 0;
-
- for(tolerate_eof = 1; /* Allow EOF first time buffer is non-empty */
- (rd = fread(fbuf, 1, fbuf_size, file))
- || feof(file) == 0
- || (tolerate_eof && DynamicBuffer.length)
- ;) {
- int ecbits = 0; /* Extra consumed bits in case of PER */
- char *i_bptr;
- size_t i_size;
-
- /*
- * Copy the data over, or use the original buffer.
- */
- if(DynamicBuffer.allocated) {
- /* Append new data into the existing dynamic buffer */
- add_bytes_to_buffer(fbuf, rd);
- i_bptr = DynamicBuffer.data + DynamicBuffer.offset;
- i_size = DynamicBuffer.length;
- } else {
- i_bptr = fbuf;
- i_size = rd;
- }
-
- DEBUG("Decoding %ld bytes", (long)i_size);
-
- switch(iform) {
- case INP_BER:
- rval = ber_decode(opt_codec_ctx, pduType,
- (void **)&structure, i_bptr, i_size);
- break;
- case INP_XER:
- rval = xer_decode(opt_codec_ctx, pduType,
- (void **)&structure, i_bptr, i_size);
- break;
- case INP_PER:
- rval = uper_decode(opt_codec_ctx, pduType,
- (void **)&structure, i_bptr, i_size, 0,
- DynamicBuffer.unbits);
- ecbits = rval.consumed % 8; /* Extra bits */
- rval.consumed /= 8; /* Convert to value in bytes! */
- /* Check if input is byte-padded at the end */
- if(opt_ippad && ecbits && rval.code == RC_OK) {
- rval.consumed++;
- ecbits = 0;
- }
- break;
- }
- DEBUG("decode(%ld) consumed %ld+%db (%ld), code %d",
- (long)DynamicBuffer.length,
- (long)rval.consumed, ecbits, (long)i_size,
- rval.code);
-
- if(DynamicBuffer.allocated == 0) {
- /*
- * Flush remainder into the intermediate buffer.
- */
- if(rval.code != RC_FAIL && rval.consumed < rd) {
- add_bytes_to_buffer(fbuf + rval.consumed,
- rd - rval.consumed);
- buffer_shift_left(0, ecbits);
- DynamicBuffer.bytes_shifted = rval.consumed;
- rval.consumed = 0;
- ecbits = 0;
- }
- }
-
- /*
- * Adjust position inside the source buffer.
- */
- if(DynamicBuffer.allocated) {
- DynamicBuffer.offset += rval.consumed;
- DynamicBuffer.length -= rval.consumed;
- } else {
- DynamicBuffer.bytes_shifted += rval.consumed;
- }
-
- switch(rval.code) {
- case RC_OK:
- if(ecbits) buffer_shift_left(0, ecbits);
- DEBUG("RC_OK, finishing up with %ld+%d",
- (long)rval.consumed, ecbits);
- return structure;
- case RC_WMORE:
- DEBUG("RC_WMORE, continuing read=%ld, cons=%ld "
- " with %ld..%ld-%ld..%ld",
- (long)rd,
- (long)rval.consumed,
- (long)DynamicBuffer.offset,
- (long)DynamicBuffer.length,
- (long)DynamicBuffer.unbits,
- (long)DynamicBuffer.allocated);
- if(!rd) tolerate_eof--;
- continue;
- case RC_FAIL:
- break;
- }
- break;
- }
-
- /* Clean up partially decoded structure */
- ASN_STRUCT_FREE(*pduType, structure);
-
- new_offset = DynamicBuffer.bytes_shifted + DynamicBuffer.offset;
-
- /*
- * Print a message and return failure only if not EOF,
- * unless this is our first PDU (empty file).
- */
- if(on_first_pdu
- || DynamicBuffer.length
- || new_offset - old_offset > ((iform == INP_XER)?sizeof("\r\n")-1:0)
- ) {
- DEBUG("ofp %d, no=%ld, oo=%ld, dbl=%ld",
- on_first_pdu, (long)new_offset, (long)old_offset,
- (long)DynamicBuffer.length);
- fprintf(stderr, "%s: "
- "Decode failed past byte %ld: %s\n",
- name, (long)new_offset,
- (rval.code == RC_WMORE)
- ? "Unexpected end of input"
- : "Input processing error");
-#ifndef ENOMSG
-#define ENOMSG EINVAL
-#endif
-#ifndef EBADMSG
-#define EBADMSG EINVAL
-#endif
- errno = (rval.code == RC_WMORE) ? ENOMSG : EBADMSG;
- } else {
- /* Got EOF after a few successful PDUs */
- errno = 0;
- }
-
- return 0;
-}
-
-/* Dump the buffer out to the specified FILE */
-static int write_out(const void *buffer, size_t size, void *key) {
- FILE *fp = (FILE *)key;
- return (fwrite(buffer, 1, size, fp) == size) ? 0 : -1;
-}
-
-static int argument_is_stdin(char *av[], int idx) {
- if(strcmp(av[idx], "-")) {
- return 0; /* Certainly not <stdin> */
- } else {
- /* This might be <stdin>, unless `./program -- -` */
- if(strcmp(av[-1], "--"))
- return 1;
- else
- return 0;
- }
-}
-
-static FILE *argument_to_file(char *av[], int idx) {
- return argument_is_stdin(av, idx)
- ? stdin
- : fopen(av[idx], "r");
-}
-
-static char *argument_to_name(char *av[], int idx) {
- return argument_is_stdin(av, idx)
- ? "standard input"
- : av[idx];
-}
+++ /dev/null
-/*-
- * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-#include <asn_internal.h>
-#include <errno.h>
-
-static ssize_t der_write_TL(ber_tlv_tag_t tag, ber_tlv_len_t len,
- asn_app_consume_bytes_f *cb, void *app_key, int constructed);
-
-/*
- * The DER encoder of any type.
- */
-asn_enc_rval_t
-der_encode(asn_TYPE_descriptor_t *type_descriptor, void *struct_ptr,
- asn_app_consume_bytes_f *consume_bytes, void *app_key) {
-
- ASN_DEBUG("DER encoder invoked for %s",
- type_descriptor->name);
-
- /*
- * Invoke type-specific encoder.
- */
- return type_descriptor->der_encoder(type_descriptor,
- struct_ptr, /* Pointer to the destination structure */
- 0, 0,
- consume_bytes, app_key);
-}
-
-/*
- * Argument type and callback necessary for der_encode_to_buffer().
- */
-typedef struct enc_to_buf_arg {
- void *buffer;
- size_t left;
-} enc_to_buf_arg;
-static int encode_to_buffer_cb(const void *buffer, size_t size, void *key) {
- enc_to_buf_arg *arg = (enc_to_buf_arg *)key;
-
- if(arg->left < size)
- return -1; /* Data exceeds the available buffer size */
-
- memcpy(arg->buffer, buffer, size);
- arg->buffer = ((char *)arg->buffer) + size;
- arg->left -= size;
-
- return 0;
-}
-
-/*
- * A variant of the der_encode() which encodes the data into the provided buffer
- */
-asn_enc_rval_t
-der_encode_to_buffer(asn_TYPE_descriptor_t *type_descriptor, void *struct_ptr,
- void *buffer, size_t buffer_size) {
- enc_to_buf_arg arg;
- asn_enc_rval_t ec;
-
- arg.buffer = buffer;
- arg.left = buffer_size;
-
- ec = type_descriptor->der_encoder(type_descriptor,
- struct_ptr, /* Pointer to the destination structure */
- 0, 0, encode_to_buffer_cb, &arg);
- if(ec.encoded != -1) {
- assert(ec.encoded == (ssize_t)(buffer_size - arg.left));
- /* Return the encoded contents size */
- }
- return ec;
-}
-
-
-/*
- * Write out leading TL[v] sequence according to the type definition.
- */
-ssize_t
-der_write_tags(asn_TYPE_descriptor_t *sd,
- size_t struct_length,
- int tag_mode, int last_tag_form,
- ber_tlv_tag_t tag, /* EXPLICIT or IMPLICIT tag */
- asn_app_consume_bytes_f *cb,
- void *app_key) {
- ber_tlv_tag_t *tags; /* Copy of tags stream */
- int tags_count; /* Number of tags */
- size_t overall_length;
- ssize_t *lens;
- int i;
-
- ASN_DEBUG("Writing tags (%s, tm=%d, tc=%d, tag=%s, mtc=%d)",
- sd->name, tag_mode, sd->tags_count,
- ber_tlv_tag_string(tag),
- tag_mode
- ?(sd->tags_count+1
- -((tag_mode == -1) && sd->tags_count))
- :sd->tags_count
- );
-
- if(tag_mode) {
- /*
- * Instead of doing shaman dance like we do in ber_check_tags(),
- * allocate a small array on the stack
- * and initialize it appropriately.
- */
- int stag_offset;
- tags = (ber_tlv_tag_t *)alloca((sd->tags_count + 1) * sizeof(ber_tlv_tag_t));
- if(!tags) { /* Can fail on !x86 */
- errno = ENOMEM;
- return -1;
- }
- tags_count = sd->tags_count
- + 1 /* EXPLICIT or IMPLICIT tag is given */
- - ((tag_mode == -1) && sd->tags_count);
- /* Copy tags over */
- tags[0] = tag;
- stag_offset = -1 + ((tag_mode == -1) && sd->tags_count);
- for(i = 1; i < tags_count; i++)
- tags[i] = sd->tags[i + stag_offset];
- } else {
- tags = sd->tags;
- tags_count = sd->tags_count;
- }
-
- /* No tags to write */
- if(tags_count == 0)
- return 0;
-
- lens = (ssize_t *)alloca(tags_count * sizeof(lens[0]));
- if(!lens) {
- errno = ENOMEM;
- return -1;
- }
-
- /*
- * Array of tags is initialized.
- * Now, compute the size of the TLV pairs, from right to left.
- */
- overall_length = struct_length;
- for(i = tags_count - 1; i >= 0; --i) {
- lens[i] = der_write_TL(tags[i], overall_length, 0, 0, 0);
- if(lens[i] == -1) return -1;
- overall_length += lens[i];
- lens[i] = overall_length - lens[i];
- }
-
- if(!cb) return overall_length - struct_length;
-
- ASN_DEBUG("%s %s TL sequence (%d elements)",
- cb?"Encoding":"Estimating", sd->name, tags_count);
-
- /*
- * Encode the TL sequence for real.
- */
- for(i = 0; i < tags_count; i++) {
- ssize_t len;
- int _constr;
-
- /* Check if this tag happens to be constructed */
- _constr = (last_tag_form || i < (tags_count - 1));
-
- len = der_write_TL(tags[i], lens[i], cb, app_key, _constr);
- if(len == -1) return -1;
- }
-
- return overall_length - struct_length;
-}
-
-static ssize_t
-der_write_TL(ber_tlv_tag_t tag, ber_tlv_len_t len,
- asn_app_consume_bytes_f *cb, void *app_key,
- int constructed) {
- uint8_t buf[32];
- size_t size = 0;
- int buf_size = cb?sizeof(buf):0;
- ssize_t tmp;
-
- /* Serialize tag (T from TLV) into possibly zero-length buffer */
- tmp = ber_tlv_tag_serialize(tag, buf, buf_size);
- if(tmp == -1 || tmp > (ssize_t)sizeof(buf)) return -1;
- size += tmp;
-
- /* Serialize length (L from TLV) into possibly zero-length buffer */
- tmp = der_tlv_length_serialize(len, buf+size, buf_size?buf_size-size:0);
- if(tmp == -1) return -1;
- size += tmp;
-
- if(size > sizeof(buf))
- return -1;
-
- /*
- * If callback is specified, invoke it, and check its return value.
- */
- if(cb) {
- if(constructed) *buf |= 0x20;
- if(cb(buf, size, app_key) < 0)
- return -1;
- }
-
- return size;
-}
+++ /dev/null
-/*-
- * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-#ifndef _DER_ENCODER_H_
-#define _DER_ENCODER_H_
-
-#include <asn_application.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct asn_TYPE_descriptor_s; /* Forward declaration */
-
-/*
- * The DER encoder of any type. May be invoked by the application.
- */
-asn_enc_rval_t der_encode(struct asn_TYPE_descriptor_s *type_descriptor,
- void *struct_ptr, /* Structure to be encoded */
- asn_app_consume_bytes_f *consume_bytes_cb,
- void *app_key /* Arbitrary callback argument */
- );
-
-/* A variant of der_encode() which encodes data into the pre-allocated buffer */
-asn_enc_rval_t der_encode_to_buffer(
- struct asn_TYPE_descriptor_s *type_descriptor,
- void *struct_ptr, /* Structure to be encoded */
- void *buffer, /* Pre-allocated buffer */
- size_t buffer_size /* Initial buffer size (maximum) */
- );
-
-/*
- * Type of the generic DER encoder.
- */
-typedef asn_enc_rval_t (der_type_encoder_f)(
- struct asn_TYPE_descriptor_s *type_descriptor,
- void *struct_ptr, /* Structure to be encoded */
- int tag_mode, /* {-1,0,1}: IMPLICIT, no, EXPLICIT */
- ber_tlv_tag_t tag,
- asn_app_consume_bytes_f *consume_bytes_cb, /* Callback */
- void *app_key /* Arbitrary callback argument */
- );
-
-
-/*******************************
- * INTERNALLY USEFUL FUNCTIONS *
- *******************************/
-
-/*
- * Write out leading TL[v] sequence according to the type definition.
- */
-ssize_t der_write_tags(
- struct asn_TYPE_descriptor_s *type_descriptor,
- size_t struct_length,
- int tag_mode, /* {-1,0,1}: IMPLICIT, no, EXPLICIT */
- int last_tag_form, /* {0,!0}: prim, constructed */
- ber_tlv_tag_t tag,
- asn_app_consume_bytes_f *consume_bytes_cb,
- void *app_key
- );
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _DER_ENCODER_H_ */
+++ /dev/null
-#include <asn_application.h>
-#include <asn_internal.h>
-#include <per_decoder.h>
-
-asn_dec_rval_t
-uper_decode(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, void **sptr, const void *buffer, size_t size, int skip_bits, int unused_bits) {
- asn_codec_ctx_t s_codec_ctx;
- asn_dec_rval_t rval;
- asn_per_data_t pd;
-
- if(skip_bits < 0 || skip_bits > 7
- || unused_bits < 0 || unused_bits > 7
- || (unused_bits > 0 && !size))
- _ASN_DECODE_FAILED;
-
- /*
- * Stack checker requires that the codec context
- * must be allocated on the stack.
- */
- if(opt_codec_ctx) {
- if(opt_codec_ctx->max_stack_size) {
- s_codec_ctx = *opt_codec_ctx;
- opt_codec_ctx = &s_codec_ctx;
- }
- } else {
- /* If context is not given, be security-conscious anyway */
- memset(&s_codec_ctx, 0, sizeof(s_codec_ctx));
- s_codec_ctx.max_stack_size = _ASN_DEFAULT_STACK_MAX;
- opt_codec_ctx = &s_codec_ctx;
- }
-
- /* Fill in the position indicator */
- pd.buffer = (const uint8_t *)buffer;
- pd.nboff = skip_bits;
- pd.nbits = 8 * size - unused_bits; /* 8 is CHAR_BIT from <limits.h> */
- if(pd.nboff > pd.nbits)
- _ASN_DECODE_FAILED;
-
- /*
- * Invoke type-specific decoder.
- */
- if(!td->uper_decoder)
- _ASN_DECODE_FAILED; /* PER is not compiled in */
- rval = td->uper_decoder(opt_codec_ctx, td, 0, sptr, &pd);
- if(rval.code == RC_OK) {
- /* Return the number of consumed bits */
- rval.consumed = ((pd.buffer - (const uint8_t *)buffer) << 3)
- + pd.nboff - skip_bits;
- } else {
- /* PER codec is not a restartable */
- rval.consumed = 0;
- }
- return rval;
-}
-
+++ /dev/null
-/*-
- * Copyright (c) 2005 Lev Walkin <vlm@lionet.info>. All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-#ifndef _PER_DECODER_H_
-#define _PER_DECODER_H_
-
-#include <asn_application.h>
-#include <per_support.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct asn_TYPE_descriptor_s; /* Forward declaration */
-
-/*
- * Unaligned PER decoder of any ASN.1 type. May be invoked by the application.
- */
-asn_dec_rval_t uper_decode(struct asn_codec_ctx_s *opt_codec_ctx,
- struct asn_TYPE_descriptor_s *type_descriptor, /* Type to decode */
- void **struct_ptr, /* Pointer to a target structure's pointer */
- const void *buffer, /* Data to be decoded */
- size_t size, /* Size of data buffer */
- int skip_bits, /* Number of unused leading bits, 0..7 */
- int unused_bits /* Number of unused tailing bits, 0..7 */
- );
-
-
-/*
- * Type of the type-specific PER decoder function.
- */
-typedef asn_dec_rval_t (per_type_decoder_f)(asn_codec_ctx_t *opt_codec_ctx,
- struct asn_TYPE_descriptor_s *type_descriptor,
- asn_per_constraints_t *constraints,
- void **struct_ptr,
- asn_per_data_t *per_data
- );
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PER_DECODER_H_ */
+++ /dev/null
-#include <asn_application.h>
-#include <asn_internal.h>
-#include <per_encoder.h>
-
-/* Flush partially filled buffer */
-static int _uper_encode_flush_outp(asn_per_outp_t *po);
-
-asn_enc_rval_t
-uper_encode(asn_TYPE_descriptor_t *td, void *sptr, asn_app_consume_bytes_f *cb, void *app_key) {
- asn_per_outp_t po;
- asn_enc_rval_t er;
-
- /*
- * Invoke type-specific encoder.
- */
- if(!td || !td->uper_encoder)
- _ASN_ENCODE_FAILED; /* PER is not compiled in */
-
- po.buffer = po.tmpspace;
- po.nboff = 0;
- po.nbits = 8 * sizeof(po.tmpspace);
- po.outper = cb;
- po.op_key = app_key;
- po.flushed_bytes = 0;
-
- er = td->uper_encoder(td, 0, sptr, &po);
- if(er.encoded != -1) {
- size_t bits_to_flush;
-
- bits_to_flush = ((po.buffer - po.tmpspace) << 3) + po.nboff;
-
- /* Set number of bits encoded to a firm value */
- er.encoded = (po.flushed_bytes << 3) + bits_to_flush;
-
- if(_uper_encode_flush_outp(&po))
- _ASN_ENCODE_FAILED;
- }
-
- return er;
-}
-
-/*
- * Argument type and callback necessary for uper_encode_to_buffer().
- */
-typedef struct enc_to_buf_arg {
- void *buffer;
- size_t left;
-} enc_to_buf_arg;
-static int encode_to_buffer_cb(const void *buffer, size_t size, void *key) {
- enc_to_buf_arg *arg = (enc_to_buf_arg *)key;
-
- if(arg->left < size)
- return -1; /* Data exceeds the available buffer size */
-
- memcpy(arg->buffer, buffer, size);
- arg->buffer = ((char *)arg->buffer) + size;
- arg->left -= size;
-
- return 0;
-}
-
-asn_enc_rval_t
-uper_encode_to_buffer(asn_TYPE_descriptor_t *td, void *sptr, void *buffer, size_t buffer_size) {
- enc_to_buf_arg key;
-
- /*
- * Invoke type-specific encoder.
- */
- if(!td || !td->uper_encoder)
- _ASN_ENCODE_FAILED; /* PER is not compiled in */
-
- key.buffer = buffer;
- key.left = buffer_size;
-
- ASN_DEBUG("Encoding \"%s\" using UNALIGNED PER", td->name);
-
- return uper_encode(td, sptr, encode_to_buffer_cb, &key);
-}
-
-static int
-_uper_encode_flush_outp(asn_per_outp_t *po) {
- uint8_t *buf;
-
- if(po->nboff == 0 && po->buffer == po->tmpspace)
- return 0;
-
- buf = po->buffer + (po->nboff >> 3);
- /* Make sure we account for the last, partially filled */
- if(po->nboff & 0x07) {
- buf[0] &= 0xff << (8 - (po->nboff & 0x07));
- buf++;
- }
-
- return po->outper(po->tmpspace, buf - po->tmpspace, po->op_key);
-}
+++ /dev/null
-/*-
- * Copyright (c) 2006 Lev Walkin <vlm@lionet.info>. All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-#ifndef _PER_ENCODER_H_
-#define _PER_ENCODER_H_
-
-#include <asn_application.h>
-#include <per_support.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct asn_TYPE_descriptor_s; /* Forward declaration */
-
-/*
- * Unaligned PER encoder of any ASN.1 type. May be invoked by the application.
- */
-asn_enc_rval_t uper_encode(struct asn_TYPE_descriptor_s *type_descriptor,
- void *struct_ptr, /* Structure to be encoded */
- asn_app_consume_bytes_f *consume_bytes_cb, /* Data collector */
- void *app_key /* Arbitrary callback argument */
-);
-
-/* A variant of uper_encode() which encodes data into the existing buffer */
-asn_enc_rval_t uper_encode_to_buffer(
- struct asn_TYPE_descriptor_s *type_descriptor,
- void *struct_ptr, /* Structure to be encoded */
- void *buffer, /* Pre-allocated buffer */
- size_t buffer_size /* Initial buffer size (max) */
-);
-
-
-/*
- * Type of the generic PER encoder function.
- */
-typedef asn_enc_rval_t (per_type_encoder_f)(
- struct asn_TYPE_descriptor_s *type_descriptor,
- asn_per_constraints_t *constraints,
- void *struct_ptr,
- asn_per_outp_t *per_output
-);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PER_ENCODER_H_ */
+++ /dev/null
-/*
- * Copyright (c) 2005, 2006 Lev Walkin <vlm@lionet.info>. All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-#include <asn_system.h>
-#include <asn_internal.h>
-#include <per_support.h>
-
-/*
- * Extract a small number of bits (<= 31) from the specified PER data pointer.
- */
-int32_t
-per_get_few_bits(asn_per_data_t *pd, int nbits) {
- size_t off; /* Next after last bit offset */
- uint32_t accum;
- const uint8_t *buf;
-
- if(nbits < 0 || pd->nboff + nbits > pd->nbits)
- return -1;
-
- ASN_DEBUG("[PER get %d bits from %p+%d bits]",
- nbits, pd->buffer, pd->nboff);
-
- /*
- * Normalize position indicator.
- */
- if(pd->nboff >= 8) {
- pd->buffer += (pd->nboff >> 3);
- pd->nbits -= (pd->nboff & ~0x07);
- pd->nboff &= 0x07;
- }
- off = (pd->nboff += nbits);
- buf = pd->buffer;
-
- /*
- * Extract specified number of bits.
- */
- if(off <= 8)
- accum = nbits ? (buf[0]) >> (8 - off) : 0;
- else if(off <= 16)
- accum = ((buf[0] << 8) + buf[1]) >> (16 - off);
- else if(off <= 24)
- accum = ((buf[0] << 16) + (buf[1] << 8) + buf[2]) >> (24 - off);
- else if(off <= 31)
- accum = ((buf[0] << 24) + (buf[1] << 16)
- + (buf[2] << 8) + (buf[3])) >> (32 - off);
- else if(nbits <= 31) {
- asn_per_data_t tpd = *pd;
- /* Here are we with our 31-bits limit plus 1..7 bits offset. */
- tpd.nboff -= nbits;
- accum = per_get_few_bits(&tpd, nbits - 24) << 24;
- accum |= per_get_few_bits(&tpd, 24);
- } else {
- pd->nboff -= nbits; /* Oops, revert back */
- return -1;
- }
-
- return (accum & (((uint32_t)1 << nbits) - 1));
-}
-
-/*
- * Extract a large number of bits from the specified PER data pointer.
- */
-int
-per_get_many_bits(asn_per_data_t *pd, uint8_t *dst, int alright, int nbits) {
- int32_t value;
-
- if(alright && (nbits & 7)) {
- /* Perform right alignment of a first few bits */
- value = per_get_few_bits(pd, nbits & 0x07);
- if(value < 0) return -1;
- *dst++ = value; /* value is already right-aligned */
- nbits &= ~7;
- }
-
- while(nbits) {
- if(nbits >= 24) {
- value = per_get_few_bits(pd, 24);
- if(value < 0) return -1;
- *(dst++) = value >> 16;
- *(dst++) = value >> 8;
- *(dst++) = value;
- nbits -= 24;
- } else {
- value = per_get_few_bits(pd, nbits);
- if(value < 0) return -1;
- if(nbits & 7) { /* implies left alignment */
- value <<= 8 - (nbits & 7),
- nbits += 8 - (nbits & 7);
- if(nbits > 24)
- *dst++ = value >> 24;
- }
- if(nbits > 16)
- *dst++ = value >> 16;
- if(nbits > 8)
- *dst++ = value >> 8;
- *dst++ = value;
- break;
- }
- }
-
- return 0;
-}
-
-/*
- * Get the length "n" from the stream.
- */
-ssize_t
-uper_get_length(asn_per_data_t *pd, int ebits, int *repeat) {
- ssize_t value;
-
- *repeat = 0;
-
- if(ebits >= 0) return per_get_few_bits(pd, ebits);
-
- value = per_get_few_bits(pd, 8);
- if(value < 0) return -1;
- if((value & 128) == 0) /* #10.9.3.6 */
- return (value & 0x7F);
- if((value & 64) == 0) { /* #10.9.3.7 */
- value = ((value & 63) << 8) | per_get_few_bits(pd, 8);
- if(value < 0) return -1;
- return value;
- }
- value &= 63; /* this is "m" from X.691, #10.9.3.8 */
- if(value < 1 || value > 4)
- return -1;
- *repeat = 1;
- return (16384 * value);
-}
-
-/*
- * Get the normally small non-negative whole number.
- * X.691, #10.6
- */
-ssize_t
-uper_get_nsnnwn(asn_per_data_t *pd) {
- ssize_t value;
-
- value = per_get_few_bits(pd, 7);
- if(value & 64) { /* implicit (value < 0) */
- value &= 63;
- value <<= 2;
- value |= per_get_few_bits(pd, 2);
- if(value & 128) /* implicit (value < 0) */
- return -1;
- if(value == 0)
- return 0;
- if(value >= 3)
- return -1;
- value = per_get_few_bits(pd, 8 * value);
- return value;
- }
-
- return value;
-}
-
-/*
- * Put the normally small non-negative whole number.
- * X.691, #10.6
- */
-int
-uper_put_nsnnwn(asn_per_outp_t *po, int n) {
- int bytes;
-
- if(n <= 63) {
- if(n < 0) return -1;
- return per_put_few_bits(po, n, 7);
- }
- if(n < 256)
- bytes = 1;
- else if(n < 65536)
- bytes = 2;
- else if(n < 256 * 65536)
- bytes = 3;
- else
- return -1; /* This is not a "normally small" value */
- if(per_put_few_bits(po, bytes, 8))
- return -1;
-
- return per_put_few_bits(po, n, 8 * bytes);
-}
-
-
-/*
- * Put a small number of bits (<= 31).
- */
-int
-per_put_few_bits(asn_per_outp_t *po, uint32_t bits, int obits) {
- size_t off; /* Next after last bit offset */
- size_t omsk; /* Existing last byte meaningful bits mask */
- uint8_t *buf;
-
- if(obits <= 0 || obits >= 32) return obits ? -1 : 0;
-
- ASN_DEBUG("[PER put %d bits to %p+%d bits]",
- obits, po->buffer, po->nboff);
-
- /*
- * Normalize position indicator.
- */
- if(po->nboff >= 8) {
- po->buffer += (po->nboff >> 3);
- po->nbits -= (po->nboff & ~0x07);
- po->nboff &= 0x07;
- }
-
- /*
- * Flush whole-bytes output, if necessary.
- */
- if(po->nboff + obits > po->nbits) {
- int complete_bytes = (po->buffer - po->tmpspace);
- if(po->outper(po->buffer, complete_bytes, po->op_key) < 0)
- return -1;
- if(po->nboff)
- po->tmpspace[0] = po->buffer[0];
- po->buffer = po->tmpspace;
- po->nbits = 8 * sizeof(po->tmpspace);
- po->flushed_bytes += complete_bytes;
- }
-
- /*
- * Now, due to sizeof(tmpspace), we are guaranteed large enough space.
- */
- buf = po->buffer;
- omsk = ~((1 << (8 - po->nboff)) - 1);
- off = (po->nboff += obits);
-
- /* Clear data of debris before meaningful bits */
- bits &= (((uint32_t)1 << obits) - 1);
-
- ASN_DEBUG("[PER out %d %u/%x (t=%d,o=%d) %x&%x=%x]", obits, bits, bits,
- po->nboff - obits, off, buf[0], omsk&0xff, buf[0] & omsk);
-
- if(off <= 8) /* Completely within 1 byte */
- bits <<= (8 - off),
- buf[0] = (buf[0] & omsk) | bits;
- else if(off <= 16)
- bits <<= (16 - off),
- buf[0] = (buf[0] & omsk) | (bits >> 8),
- buf[1] = bits;
- else if(off <= 24)
- bits <<= (24 - off),
- buf[0] = (buf[0] & omsk) | (bits >> 16),
- buf[1] = bits >> 8,
- buf[2] = bits;
- else if(off <= 31)
- bits <<= (32 - off),
- buf[0] = (buf[0] & omsk) | (bits >> 24),
- buf[1] = bits >> 16,
- buf[2] = bits >> 8,
- buf[3] = bits;
- else {
- ASN_DEBUG("->[PER out split %d]", obits);
- per_put_few_bits(po, bits >> 8, 24);
- per_put_few_bits(po, bits, obits - 24);
- ASN_DEBUG("<-[PER out split %d]", obits);
- }
-
- ASN_DEBUG("[PER out %u/%x => %02x buf+%d]",
- bits, bits, buf[0], po->buffer - po->tmpspace);
-
- return 0;
-}
-
-
-/*
- * Output a large number of bits.
- */
-int
-per_put_many_bits(asn_per_outp_t *po, const uint8_t *src, int nbits) {
-
- while(nbits) {
- uint32_t value;
-
- if(nbits >= 24) {
- value = (src[0] << 16) | (src[1] << 8) | src[2];
- src += 3;
- nbits -= 24;
- if(per_put_few_bits(po, value, 24))
- return -1;
- } else {
- value = src[0];
- if(nbits > 8)
- value = (value << 8) | src[1];
- if(nbits > 16)
- value = (value << 8) | src[2];
- if(nbits & 0x07)
- value >>= (8 - (nbits & 0x07));
- if(per_put_few_bits(po, value, nbits))
- return -1;
- break;
- }
- }
-
- return 0;
-}
-
-/*
- * Put the length "n" (or part of it) into the stream.
- */
-ssize_t
-uper_put_length(asn_per_outp_t *po, size_t length) {
-
- if(length <= 127) /* #10.9.3.6 */
- return per_put_few_bits(po, length, 8)
- ? -1 : (ssize_t)length;
- else if(length < 16384) /* #10.9.3.7 */
- return per_put_few_bits(po, length|0x8000, 16)
- ? -1 : (ssize_t)length;
-
- length >>= 14;
- if(length > 4) length = 4;
-
- return per_put_few_bits(po, 0xC0 | length, 8)
- ? -1 : (ssize_t)(length << 14);
-}
-
+++ /dev/null
-/*
- * Copyright (c) 2005, 2006 Lev Walkin <vlm@lionet.info>. All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-#ifndef _PER_SUPPORT_H_
-#define _PER_SUPPORT_H_
-
-#include <asn_system.h> /* Platform-specific types */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Pre-computed PER constraints.
- */
-typedef struct asn_per_constraint_s {
- enum asn_per_constraint_flags {
- APC_UNCONSTRAINED = 0x0, /* No PER visible constraints */
- APC_SEMI_CONSTRAINED = 0x1, /* Constrained at "lb" */
- APC_CONSTRAINED = 0x2, /* Fully constrained */
- APC_EXTENSIBLE = 0x4 /* May have extension */
- } flags;
- int range_bits; /* Full number of bits in the range */
- int effective_bits; /* Effective bits */
- long lower_bound; /* "lb" value */
- long upper_bound; /* "ub" value */
-} asn_per_constraint_t;
-typedef struct asn_per_constraints_s {
- asn_per_constraint_t value;
- asn_per_constraint_t size;
-} asn_per_constraints_t;
-
-/*
- * This structure describes a position inside an incoming PER bit stream.
- */
-typedef struct asn_per_data_s {
- const uint8_t *buffer; /* Pointer to the octet stream */
- size_t nboff; /* Bit offset to the meaningful bit */
- size_t nbits; /* Number of bits in the stream */
-} asn_per_data_t;
-
-/*
- * Extract a small number of bits (<= 31) from the specified PER data pointer.
- * This function returns -1 if the specified number of bits could not be
- * extracted due to EOD or other conditions.
- */
-int32_t per_get_few_bits(asn_per_data_t *per_data, int get_nbits);
-
-/*
- * Extract a large number of bits from the specified PER data pointer.
- * This function returns -1 if the specified number of bits could not be
- * extracted due to EOD or other conditions.
- */
-int per_get_many_bits(asn_per_data_t *pd, uint8_t *dst, int right_align,
- int get_nbits);
-
-/*
- * Get the length "n" from the Unaligned PER stream.
- */
-ssize_t uper_get_length(asn_per_data_t *pd,
- int effective_bound_bits,
- int *repeat);
-
-/*
- * Get the normally small non-negative whole number.
- */
-ssize_t uper_get_nsnnwn(asn_per_data_t *pd);
-
-/*
- * This structure supports forming PER output.
- */
-typedef struct asn_per_outp_s {
- uint8_t *buffer; /* Pointer into the (tmpspace) */
- size_t nboff; /* Bit offset to the meaningful bit */
- size_t nbits; /* Number of bits left in (tmpspace) */
- uint8_t tmpspace[32]; /* Preliminary storage to hold data */
- int (*outper)(const void *data, size_t size, void *op_key);
- void *op_key; /* Key for (outper) data callback */
- size_t flushed_bytes; /* Bytes already flushed through (outper) */
-} asn_per_outp_t;
-
-/* Output a small number of bits (<= 31) */
-int per_put_few_bits(asn_per_outp_t *per_data, uint32_t bits, int obits);
-
-/* Output a large number of bits */
-int per_put_many_bits(asn_per_outp_t *po, const uint8_t *src, int put_nbits);
-
-/*
- * Put the length "n" to the Unaligned PER stream.
- * This function returns the number of units which may be flushed
- * in the next units saving iteration.
- */
-ssize_t uper_put_length(asn_per_outp_t *po, size_t whole_length);
-
-/*
- * Put the normally small non-negative whole number.
- */
-int uper_put_nsnnwn(asn_per_outp_t *po, int n);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PER_SUPPORT_H_ */
+++ /dev/null
-/*
- * Copyright (c) 2004, 2005 Lev Walkin <vlm@lionet.info>. All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-#include <asn_application.h>
-#include <asn_internal.h>
-#include <xer_support.h> /* XER/XML parsing support */
-
-
-/*
- * Decode the XER encoding of a given type.
- */
-asn_dec_rval_t
-xer_decode(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
- void **struct_ptr, const void *buffer, size_t size) {
- asn_codec_ctx_t s_codec_ctx;
-
- /*
- * Stack checker requires that the codec context
- * must be allocated on the stack.
- */
- if(opt_codec_ctx) {
- if(opt_codec_ctx->max_stack_size) {
- s_codec_ctx = *opt_codec_ctx;
- opt_codec_ctx = &s_codec_ctx;
- }
- } else {
- /* If context is not given, be security-conscious anyway */
- memset(&s_codec_ctx, 0, sizeof(s_codec_ctx));
- s_codec_ctx.max_stack_size = _ASN_DEFAULT_STACK_MAX;
- opt_codec_ctx = &s_codec_ctx;
- }
-
- /*
- * Invoke type-specific decoder.
- */
- return td->xer_decoder(opt_codec_ctx, td, struct_ptr, 0, buffer, size);
-}
-
-
-
-struct xer__cb_arg {
- pxml_chunk_type_e chunk_type;
- size_t chunk_size;
- const void *chunk_buf;
- int callback_not_invoked;
-};
-
-static int
-xer__token_cb(pxml_chunk_type_e type, const void *_chunk_data, size_t _chunk_size, void *key) {
- struct xer__cb_arg *arg = (struct xer__cb_arg *)key;
- arg->chunk_type = type;
- arg->chunk_size = _chunk_size;
- arg->chunk_buf = _chunk_data;
- arg->callback_not_invoked = 0;
- return -1; /* Terminate the XML parsing */
-}
-
-/*
- * Fetch the next token from the XER/XML stream.
- */
-ssize_t
-xer_next_token(int *stateContext, const void *buffer, size_t size, pxer_chunk_type_e *ch_type) {
- struct xer__cb_arg arg;
- int new_stateContext = *stateContext;
- ssize_t ret;
-
- arg.callback_not_invoked = 1;
- ret = pxml_parse(&new_stateContext, buffer, size, xer__token_cb, &arg);
- if(ret < 0) return -1;
- if(arg.callback_not_invoked) {
- assert(ret == 0); /* No data was consumed */
- return 0; /* Try again with more data */
- } else {
- assert(arg.chunk_size);
- assert(arg.chunk_buf == buffer);
- }
-
- /*
- * Translate the XML chunk types into more convenient ones.
- */
- switch(arg.chunk_type) {
- case PXML_TEXT:
- *ch_type = PXER_TEXT;
- break;
- case PXML_TAG: return 0; /* Want more */
- case PXML_TAG_END:
- *ch_type = PXER_TAG;
- break;
- case PXML_COMMENT:
- case PXML_COMMENT_END:
- *ch_type = PXER_COMMENT;
- break;
- }
-
- *stateContext = new_stateContext;
- return arg.chunk_size;
-}
-
-#define CSLASH 0x2f /* '/' */
-#define LANGLE 0x3c /* '<' */
-#define RANGLE 0x3e /* '>' */
-
-xer_check_tag_e
-xer_check_tag(const void *buf_ptr, int size, const char *need_tag) {
- const char *buf = (const char *)buf_ptr;
- const char *end;
- xer_check_tag_e ct = XCT_OPENING;
-
- if(size < 2 || buf[0] != LANGLE || buf[size-1] != RANGLE) {
- if(size >= 2)
- ASN_DEBUG("Broken XML tag: \"%c...%c\"", buf[0], buf[size - 1]);
- return XCT_BROKEN;
- }
-
- /*
- * Determine the tag class.
- */
- if(buf[1] == CSLASH) {
- buf += 2; /* advance past "</" */
- size -= 3; /* strip "</" and ">" */
- ct = XCT_CLOSING;
- if(size > 0 && buf[size-1] == CSLASH)
- return XCT_BROKEN; /* </abc/> */
- } else {
- buf++; /* advance past "<" */
- size -= 2; /* strip "<" and ">" */
- if(size > 0 && buf[size-1] == CSLASH) {
- ct = XCT_BOTH;
- size--; /* One more, for "/" */
- }
- }
-
- /* Sometimes we don't care about the tag */
- if(!need_tag || !*need_tag)
- return (xer_check_tag_e)(XCT__UNK__MASK | ct);
-
- /*
- * Determine the tag name.
- */
- for(end = buf + size; buf < end; buf++, need_tag++) {
- int b = *buf, n = *need_tag;
- if(b != n) {
- if(n == 0) {
- switch(b) {
- case 0x09: case 0x0a: case 0x0c: case 0x0d:
- case 0x20:
- /* "<abc def/>": whitespace is normal */
- return ct;
- }
- }
- return (xer_check_tag_e)(XCT__UNK__MASK | ct);
- }
- if(b == 0)
- return XCT_BROKEN; /* Embedded 0 in buf?! */
- }
- if(*need_tag)
- return (xer_check_tag_e)(XCT__UNK__MASK | ct);
-
- return ct;
-}
-
-
-#undef ADVANCE
-#define ADVANCE(num_bytes) do { \
- size_t num = (num_bytes); \
- buf_ptr = ((const char *)buf_ptr) + num; \
- size -= num; \
- consumed_myself += num; \
- } while(0)
-
-#undef RETURN
-#define RETURN(_code) do { \
- rval.code = _code; \
- rval.consumed = consumed_myself; \
- if(rval.code != RC_OK) \
- ASN_DEBUG("Failed with %d", rval.code); \
- return rval; \
- } while(0)
-
-#define XER_GOT_BODY(chunk_buf, chunk_size, size) do { \
- ssize_t converted_size = body_receiver \
- (struct_key, chunk_buf, chunk_size, \
- (size_t)chunk_size < size); \
- if(converted_size == -1) RETURN(RC_FAIL); \
- if(converted_size == 0 \
- && size == (size_t)chunk_size) \
- RETURN(RC_WMORE); \
- chunk_size = converted_size; \
- } while(0)
-#define XER_GOT_EMPTY() do { \
- if(body_receiver(struct_key, 0, 0, size > 0) == -1) \
- RETURN(RC_FAIL); \
- } while(0)
-
-/*
- * Generalized function for decoding the primitive values.
- */
-asn_dec_rval_t
-xer_decode_general(asn_codec_ctx_t *opt_codec_ctx,
- asn_struct_ctx_t *ctx, /* Type decoder context */
- void *struct_key,
- const char *xml_tag, /* Expected XML tag */
- const void *buf_ptr, size_t size,
- int (*opt_unexpected_tag_decoder)
- (void *struct_key, const void *chunk_buf, size_t chunk_size),
- ssize_t (*body_receiver)
- (void *struct_key, const void *chunk_buf, size_t chunk_size,
- int have_more)
- ) {
-
- asn_dec_rval_t rval;
- ssize_t consumed_myself = 0;
-
- (void)opt_codec_ctx;
-
- /*
- * Phases of XER/XML processing:
- * Phase 0: Check that the opening tag matches our expectations.
- * Phase 1: Processing body and reacting on closing tag.
- */
- if(ctx->phase > 1) RETURN(RC_FAIL);
- for(;;) {
- pxer_chunk_type_e ch_type; /* XER chunk type */
- ssize_t ch_size; /* Chunk size */
- xer_check_tag_e tcv; /* Tag check value */
-
- /*
- * Get the next part of the XML stream.
- */
- ch_size = xer_next_token(&ctx->context, buf_ptr, size,
- &ch_type);
- switch(ch_size) {
- case -1: RETURN(RC_FAIL);
- case 0:
- RETURN(RC_WMORE);
- default:
- switch(ch_type) {
- case PXER_COMMENT: /* Got XML comment */
- ADVANCE(ch_size); /* Skip silently */
- continue;
- case PXER_TEXT:
- if(ctx->phase == 0) {
- /*
- * We have to ignore whitespace here,
- * but in order to be forward compatible
- * with EXTENDED-XER (EMBED-VALUES, #25)
- * any text is just ignored here.
- */
- } else {
- XER_GOT_BODY(buf_ptr, ch_size, size);
- }
- ADVANCE(ch_size);
- continue;
- case PXER_TAG:
- break; /* Check the rest down there */
- }
- }
-
- assert(ch_type == PXER_TAG && size);
-
- tcv = xer_check_tag(buf_ptr, ch_size, xml_tag);
- /*
- * Phase 0:
- * Expecting the opening tag
- * for the type being processed.
- * Phase 1:
- * Waiting for the closing XML tag.
- */
- switch(tcv) {
- case XCT_BOTH:
- if(ctx->phase) break;
- /* Finished decoding of an empty element */
- XER_GOT_EMPTY();
- ADVANCE(ch_size);
- ctx->phase = 2; /* Phase out */
- RETURN(RC_OK);
- case XCT_OPENING:
- if(ctx->phase) break;
- ADVANCE(ch_size);
- ctx->phase = 1; /* Processing body phase */
- continue;
- case XCT_CLOSING:
- if(!ctx->phase) break;
- ADVANCE(ch_size);
- ctx->phase = 2; /* Phase out */
- RETURN(RC_OK);
- case XCT_UNKNOWN_BO:
- /*
- * Certain tags in the body may be expected.
- */
- if(opt_unexpected_tag_decoder
- && opt_unexpected_tag_decoder(struct_key,
- buf_ptr, ch_size) >= 0) {
- /* Tag's processed fine */
- ADVANCE(ch_size);
- if(!ctx->phase) {
- /* We are not expecting
- * the closing tag anymore. */
- ctx->phase = 2; /* Phase out */
- RETURN(RC_OK);
- }
- continue;
- }
- /* Fall through */
- default:
- break; /* Unexpected tag */
- }
-
- ASN_DEBUG("Unexpected XML tag (expected \"%s\")", xml_tag);
- break; /* Dark and mysterious things have just happened */
- }
-
- RETURN(RC_FAIL);
-}
-
-
-int
-xer_is_whitespace(const void *chunk_buf, size_t chunk_size) {
- const char *p = (const char *)chunk_buf;
- const char *pend = p + chunk_size;
-
- for(; p < pend; p++) {
- switch(*p) {
- /* X.693, #8.1.4
- * HORISONTAL TAB (9)
- * LINE FEED (10)
- * CARRIAGE RETURN (13)
- * SPACE (32)
- */
- case 0x09: case 0x0a: case 0x0d: case 0x20:
- break;
- default:
- return 0;
- }
- }
- return 1; /* All whitespace */
-}
-
-/*
- * This is a vastly simplified, non-validating XML tree skipper.
- */
-int
-xer_skip_unknown(xer_check_tag_e tcv, ber_tlv_len_t *depth) {
- assert(*depth > 0);
- switch(tcv) {
- case XCT_BOTH:
- case XCT_UNKNOWN_BO:
- /* These negate each other. */
- return 0;
- case XCT_OPENING:
- case XCT_UNKNOWN_OP:
- ++(*depth);
- return 0;
- case XCT_CLOSING:
- case XCT_UNKNOWN_CL:
- if(--(*depth) == 0)
- return (tcv == XCT_CLOSING) ? 2 : 1;
- return 0;
- default:
- return -1;
- }
-}
+++ /dev/null
-/*-
- * Copyright (c) 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-#ifndef _XER_DECODER_H_
-#define _XER_DECODER_H_
-
-#include <asn_application.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct asn_TYPE_descriptor_s; /* Forward declaration */
-
-/*
- * The XER decoder of any ASN.1 type. May be invoked by the application.
- */
-asn_dec_rval_t xer_decode(struct asn_codec_ctx_s *opt_codec_ctx,
- struct asn_TYPE_descriptor_s *type_descriptor,
- void **struct_ptr, /* Pointer to a target structure's pointer */
- const void *buffer, /* Data to be decoded */
- size_t size /* Size of data buffer */
- );
-
-/*
- * Type of the type-specific XER decoder function.
- */
-typedef asn_dec_rval_t (xer_type_decoder_f)(asn_codec_ctx_t *opt_codec_ctx,
- struct asn_TYPE_descriptor_s *type_descriptor,
- void **struct_ptr,
- const char *opt_mname, /* Member name */
- const void *buf_ptr, size_t size
- );
-
-/*******************************
- * INTERNALLY USEFUL FUNCTIONS *
- *******************************/
-
-/*
- * Generalized function for decoding the primitive values.
- * Used by more specialized functions, such as OCTET_STRING_decode_xer_utf8
- * and others. This function should not be used by applications, as its API
- * is subject to changes.
- */
-asn_dec_rval_t xer_decode_general(asn_codec_ctx_t *opt_codec_ctx,
- asn_struct_ctx_t *ctx, /* Type decoder context */
- void *struct_key, /* Treated as opaque pointer */
- const char *xml_tag, /* Expected XML tag name */
- const void *buf_ptr, size_t size,
- int (*opt_unexpected_tag_decoder)
- (void *struct_key, const void *chunk_buf, size_t chunk_size),
- ssize_t (*body_receiver)
- (void *struct_key, const void *chunk_buf, size_t chunk_size,
- int have_more)
- );
-
-
-/*
- * Fetch the next XER (XML) token from the stream.
- * The function returns the number of bytes occupied by the chunk type,
- * returned in the _ch_type. The _ch_type is only set (and valid) when
- * the return value is greater than 0.
- */
- typedef enum pxer_chunk_type {
- PXER_TAG, /* Complete XER tag */
- PXER_TEXT, /* Plain text between XER tags */
- PXER_COMMENT /* A comment, may be part of */
- } pxer_chunk_type_e;
-ssize_t xer_next_token(int *stateContext,
- const void *buffer, size_t size, pxer_chunk_type_e *_ch_type);
-
-/*
- * This function checks the buffer against the tag name is expected to occur.
- */
- typedef enum xer_check_tag {
- XCT_BROKEN = 0, /* The tag is broken */
- XCT_OPENING = 1, /* This is the <opening> tag */
- XCT_CLOSING = 2, /* This is the </closing> tag */
- XCT_BOTH = 3, /* This is the <modified/> tag */
- XCT__UNK__MASK = 4, /* Mask of everything unexpected */
- XCT_UNKNOWN_OP = 5, /* Unexpected <opening> tag */
- XCT_UNKNOWN_CL = 6, /* Unexpected </closing> tag */
- XCT_UNKNOWN_BO = 7 /* Unexpected <modified/> tag */
- } xer_check_tag_e;
-xer_check_tag_e xer_check_tag(const void *buf_ptr, int size,
- const char *need_tag);
-
-/*
- * Check whether this buffer consists of entirely XER whitespace characters.
- * RETURN VALUES:
- * 1: Whitespace or empty string
- * 0: Non-whitespace
- */
-int xer_is_whitespace(const void *chunk_buf, size_t chunk_size);
-
-/*
- * Skip the series of anticipated extensions.
- */
-int xer_skip_unknown(xer_check_tag_e tcv, ber_tlv_len_t *depth);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _XER_DECODER_H_ */
+++ /dev/null
-/*-
- * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-#include <asn_internal.h>
-#include <stdio.h>
-#include <errno.h>
-
-/*
- * The XER encoder of any type. May be invoked by the application.
- */
-asn_enc_rval_t
-xer_encode(asn_TYPE_descriptor_t *td, void *sptr,
- enum xer_encoder_flags_e xer_flags,
- asn_app_consume_bytes_f *cb, void *app_key) {
- asn_enc_rval_t er, tmper;
- const char *mname;
- size_t mlen;
- int xcan = (xer_flags & XER_F_CANONICAL) ? 1 : 2;
-
- if(!td || !sptr) goto cb_failed;
-
- mname = td->xml_tag;
- mlen = strlen(mname);
-
- _ASN_CALLBACK3("<", 1, mname, mlen, ">", 1);
-
- tmper = td->xer_encoder(td, sptr, 1, xer_flags, cb, app_key);
- if(tmper.encoded == -1) return tmper;
-
- _ASN_CALLBACK3("</", 2, mname, mlen, ">\n", xcan);
-
- er.encoded = 4 + xcan + (2 * mlen) + tmper.encoded;
-
- _ASN_ENCODED_OK(er);
-cb_failed:
- _ASN_ENCODE_FAILED;
-}
-
-/*
- * This is a helper function for xer_fprint, which directs all incoming data
- * into the provided file descriptor.
- */
-static int
-xer__print2fp(const void *buffer, size_t size, void *app_key) {
- FILE *stream = (FILE *)app_key;
-
- if(fwrite(buffer, 1, size, stream) != size)
- return -1;
-
- return 0;
-}
-
-int
-xer_fprint(FILE *stream, asn_TYPE_descriptor_t *td, void *sptr) {
- asn_enc_rval_t er;
-
- if(!stream) stream = stdout;
- if(!td || !sptr)
- return -1;
-
- er = xer_encode(td, sptr, XER_F_BASIC, xer__print2fp, stream);
- if(er.encoded == -1)
- return -1;
-
- return fflush(stream);
-}
+++ /dev/null
-/*-
- * Copyright (c) 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-#ifndef _XER_ENCODER_H_
-#define _XER_ENCODER_H_
-
-#include <asn_application.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct asn_TYPE_descriptor_s; /* Forward declaration */
-
-/* Flags used by the xer_encode() and (*xer_type_encoder_f), defined below */
-enum xer_encoder_flags_e {
- /* Mode of encoding */
- XER_F_BASIC = 0x01, /* BASIC-XER (pretty-printing) */
- XER_F_CANONICAL = 0x02 /* Canonical XER (strict rules) */
-};
-
-/*
- * The XER encoder of any type. May be invoked by the application.
- */
-asn_enc_rval_t xer_encode(struct asn_TYPE_descriptor_s *type_descriptor,
- void *struct_ptr, /* Structure to be encoded */
- enum xer_encoder_flags_e xer_flags,
- asn_app_consume_bytes_f *consume_bytes_cb,
- void *app_key /* Arbitrary callback argument */
- );
-
-/*
- * The variant of the above function which dumps the BASIC-XER (XER_F_BASIC)
- * output into the chosen file pointer.
- * RETURN VALUES:
- * 0: The structure is printed.
- * -1: Problem printing the structure.
- * WARNING: No sensible errno value is returned.
- */
-int xer_fprint(FILE *stream, struct asn_TYPE_descriptor_s *td, void *sptr);
-
-/*
- * Type of the generic XER encoder.
- */
-typedef asn_enc_rval_t (xer_type_encoder_f)(
- struct asn_TYPE_descriptor_s *type_descriptor,
- void *struct_ptr, /* Structure to be encoded */
- int ilevel, /* Level of indentation */
- enum xer_encoder_flags_e xer_flags,
- asn_app_consume_bytes_f *consume_bytes_cb, /* Callback */
- void *app_key /* Arbitrary callback argument */
- );
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _XER_ENCODER_H_ */
+++ /dev/null
-/*
- * Copyright (c) 2003, 2004 X/IO Labs, xiolabs.com.
- * Copyright (c) 2003, 2004, 2005 Lev Walkin <vlm@lionet.info>.
- * All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-#include <asn_system.h>
-#include <xer_support.h>
-
-/* Parser states */
-typedef enum {
- ST_TEXT,
- ST_TAG_START,
- ST_TAG_BODY,
- ST_TAG_QUOTE_WAIT,
- ST_TAG_QUOTED_STRING,
- ST_TAG_UNQUOTED_STRING,
- ST_COMMENT_WAIT_DASH1, /* "<!--"[1] */
- ST_COMMENT_WAIT_DASH2, /* "<!--"[2] */
- ST_COMMENT,
- ST_COMMENT_CLO_DASH2, /* "-->"[0] */
- ST_COMMENT_CLO_RT /* "-->"[1] */
-} pstate_e;
-
-static pxml_chunk_type_e final_chunk_type[] = {
- PXML_TEXT,
- PXML_TAG_END,
- PXML_COMMENT_END,
- PXML_TAG_END,
- PXML_COMMENT_END,
-};
-
-
-static int
-_charclass[256] = {
- 0,0,0,0,0,0,0,0, 0,1,1,0,1,1,0,0,
- 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
- 1,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
- 2,2,2,2,2,2,2,2, 2,2,0,0,0,0,0,0, /* 01234567 89 */
- 0,3,3,3,3,3,3,3, 3,3,3,3,3,3,3,3, /* ABCDEFG HIJKLMNO */
- 3,3,3,3,3,3,3,3, 3,3,3,0,0,0,0,0, /* PQRSTUVW XYZ */
- 0,3,3,3,3,3,3,3, 3,3,3,3,3,3,3,3, /* abcdefg hijklmno */
- 3,3,3,3,3,3,3,3, 3,3,3,0,0,0,0,0 /* pqrstuvw xyz */
-};
-#define WHITESPACE(c) (_charclass[(unsigned char)(c)] == 1)
-#define ALNUM(c) (_charclass[(unsigned char)(c)] >= 2)
-#define ALPHA(c) (_charclass[(unsigned char)(c)] == 3)
-
-/* Aliases for characters, ASCII/UTF-8 */
-#define EXCLAM 0x21 /* '!' */
-#define CQUOTE 0x22 /* '"' */
-#define CDASH 0x2d /* '-' */
-#define CSLASH 0x2f /* '/' */
-#define LANGLE 0x3c /* '<' */
-#define CEQUAL 0x3d /* '=' */
-#define RANGLE 0x3e /* '>' */
-#define CQUEST 0x3f /* '?' */
-
-/* Invoke token callback */
-#define TOKEN_CB_CALL(type, _ns, _current_too, _final) do { \
- int _ret; \
- pstate_e ns = _ns; \
- ssize_t _sz = (p - chunk_start) + _current_too; \
- if (!_sz) { \
- /* Shortcut */ \
- state = _ns; \
- break; \
- } \
- _ret = cb(type, chunk_start, _sz, key); \
- if(_ret < _sz) { \
- if(_current_too && _ret == -1) \
- state = ns; \
- goto finish; \
- } \
- chunk_start = p + _current_too; \
- state = ns; \
- } while(0)
-
-#define TOKEN_CB(_type, _ns, _current_too) \
- TOKEN_CB_CALL(_type, _ns, _current_too, 0)
-
-#define TOKEN_CB_FINAL(_type, _ns, _current_too) \
- TOKEN_CB_CALL(final_chunk_type[_type], _ns, _current_too, 1)
-
-/*
- * Parser itself
- */
-ssize_t pxml_parse(int *stateContext, const void *xmlbuf, size_t size, pxml_callback_f *cb, void *key) {
- pstate_e state = (pstate_e)*stateContext;
- const char *chunk_start = (const char *)xmlbuf;
- const char *p = chunk_start;
- const char *end = p + size;
-
- for(; p < end; p++) {
- int C = *(const unsigned char *)p;
- switch(state) {
- case ST_TEXT:
- /*
- * Initial state: we're in the middle of some text,
- * or just have started.
- */
- if (C == LANGLE)
- /* We're now in the tag, probably */
- TOKEN_CB(PXML_TEXT, ST_TAG_START, 0);
- break;
- case ST_TAG_START:
- if (ALPHA(C) || (C == CSLASH))
- state = ST_TAG_BODY;
- else if (C == EXCLAM)
- state = ST_COMMENT_WAIT_DASH1;
- else
- /*
- * Not characters and not whitespace.
- * Must be something like "3 < 4".
- */
- TOKEN_CB(PXML_TEXT, ST_TEXT, 1);/* Flush as data */
- break;
- case ST_TAG_BODY:
- switch(C) {
- case RANGLE:
- /* End of the tag */
- TOKEN_CB_FINAL(PXML_TAG, ST_TEXT, 1);
- break;
- case LANGLE:
- /*
- * The previous tag wasn't completed, but still
- * recognized as valid. (Mozilla-compatible)
- */
- TOKEN_CB_FINAL(PXML_TAG, ST_TAG_START, 0);
- break;
- case CEQUAL:
- state = ST_TAG_QUOTE_WAIT;
- break;
- }
- break;
- case ST_TAG_QUOTE_WAIT:
- /*
- * State after the equal sign ("=") in the tag.
- */
- switch(C) {
- case CQUOTE:
- state = ST_TAG_QUOTED_STRING;
- break;
- case RANGLE:
- /* End of the tag */
- TOKEN_CB_FINAL(PXML_TAG, ST_TEXT, 1);
- break;
- default:
- if(!WHITESPACE(C))
- /* Unquoted string value */
- state = ST_TAG_UNQUOTED_STRING;
- }
- break;
- case ST_TAG_QUOTED_STRING:
- /*
- * Tag attribute's string value in quotes.
- */
- if(C == CQUOTE) {
- /* Return back to the tag state */
- state = ST_TAG_BODY;
- }
- break;
- case ST_TAG_UNQUOTED_STRING:
- if(C == RANGLE) {
- /* End of the tag */
- TOKEN_CB_FINAL(PXML_TAG, ST_TEXT, 1);
- } else if(WHITESPACE(C)) {
- /* Return back to the tag state */
- state = ST_TAG_BODY;
- }
- break;
- case ST_COMMENT_WAIT_DASH1:
- if(C == CDASH) {
- state = ST_COMMENT_WAIT_DASH2;
- } else {
- /* Some ordinary tag. */
- state = ST_TAG_BODY;
- }
- break;
- case ST_COMMENT_WAIT_DASH2:
- if(C == CDASH) {
- /* Seen "<--" */
- state = ST_COMMENT;
- } else {
- /* Some ordinary tag */
- state = ST_TAG_BODY;
- }
- break;
- case ST_COMMENT:
- if(C == CDASH) {
- state = ST_COMMENT_CLO_DASH2;
- }
- break;
- case ST_COMMENT_CLO_DASH2:
- if(C == CDASH) {
- state = ST_COMMENT_CLO_RT;
- } else {
- /* This is not an end of a comment */
- state = ST_COMMENT;
- }
- break;
- case ST_COMMENT_CLO_RT:
- if(C == RANGLE) {
- TOKEN_CB_FINAL(PXML_COMMENT, ST_TEXT, 1);
- } else if(C == CDASH) {
- /* Maintain current state, still waiting for '>' */
- } else {
- state = ST_COMMENT;
- }
- break;
- } /* switch(*ptr) */
- } /* for() */
-
- /*
- * Flush the partially processed chunk, state permitting.
- */
- if(p - chunk_start) {
- switch (state) {
- case ST_COMMENT:
- TOKEN_CB(PXML_COMMENT, state, 0);
- break;
- case ST_TEXT:
- TOKEN_CB(PXML_TEXT, state, 0);
- break;
- default: break; /* a no-op */
- }
- }
-
-finish:
- *stateContext = (int)state;
- return chunk_start - (const char *)xmlbuf;
-}
-
+++ /dev/null
-/*
- * Copyright (c) 2003, 2004 X/IO Labs, xiolabs.com.
- * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
- * Redistribution and modifications are permitted subject to BSD license.
- */
-#ifndef _XER_SUPPORT_H_
-#define _XER_SUPPORT_H_
-
-#include <asn_system.h> /* Platform-specific types */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Types of data transferred to the application.
- */
-typedef enum {
- PXML_TEXT, /* Plain text between XML tags. */
- PXML_TAG, /* A tag, starting with '<'. */
- PXML_COMMENT, /* An XML comment, including "<!--" and "-->". */
- /*
- * The following chunk types are reported if the chunk
- * terminates the specified XML element.
- */
- PXML_TAG_END, /* Tag ended */
- PXML_COMMENT_END /* Comment ended */
-} pxml_chunk_type_e;
-
-/*
- * Callback function that is called by the parser when parsed data is
- * available. The _opaque is the pointer to a field containing opaque user
- * data specified in pxml_create() call. The chunk type is _type and the text
- * data is the piece of buffer identified by _bufid (as supplied to
- * pxml_feed() call) starting at offset _offset and of _size bytes size.
- * The chunk is NOT '\0'-terminated.
- */
-typedef int (pxml_callback_f)(pxml_chunk_type_e _type,
- const void *_chunk_data, size_t _chunk_size, void *_key);
-
-/*
- * Parse the given buffer as it were a chunk of XML data.
- * Invoke the specified callback each time the meaninful data is found.
- * This function returns number of bytes consumed from the bufer.
- * It will always be lesser than or equal to the specified _size.
- * The next invocation of this function must account the difference.
- */
-ssize_t pxml_parse(int *_stateContext, const void *_buf, size_t _size,
- pxml_callback_f *cb, void *_key);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _XER_SUPPORT_H_ */
+++ /dev/null
-#include "asn1/INTEGER.h"
-
-#include "stg/user.h"
-#include "stg/user_property.h"
-
-#include "sensors.h"
-
-void Int2OS(ObjectSyntax_t * dst, long src)
-{
-dst->present = ObjectSyntax_PR_simple;
-SimpleSyntax_t * simpleSyntax = &dst->choice.simple;
-simpleSyntax->present = SimpleSyntax_PR_number;
-asn_long2INTEGER(&simpleSyntax->choice.number, src);
-}
-
-bool ConnectedUsersSensor::GetValue(ObjectSyntax_t * objectSyntax)
-{
-int handle = users.OpenSearch();
-if (!handle)
- return false;
-
-USER_PTR user;
-size_t count = 0;
-while (!users.SearchNext(handle, &user))
- {
- if (user->GetConnected())
- ++count;
- }
-
-users.CloseSearch(handle);
-
-Int2OS(objectSyntax, count);
-return true;
-}
-
-bool AuthorizedUsersSensor::GetValue(ObjectSyntax_t * objectSyntax)
-{
-int handle = users.OpenSearch();
-if (!handle)
- return false;
-
-USER_PTR user;
-size_t count = 0;
-while (!users.SearchNext(handle, &user))
- {
- if (user->GetAuthorized())
- ++count;
- }
-
-users.CloseSearch(handle);
-
-Int2OS(objectSyntax, count);
-return true;
-}
-
-bool AlwaysOnlineUsersSensor::GetValue(ObjectSyntax_t * objectSyntax)
-{
-int handle = users.OpenSearch();
-if (!handle)
- return false;
-
-USER_PTR user;
-size_t count = 0;
-while (!users.SearchNext(handle, &user))
- {
- if (user->GetProperty().alwaysOnline)
- ++count;
- }
-
-users.CloseSearch(handle);
-
-Int2OS(objectSyntax, count);
-return true;
-}
-
-bool NoCashUsersSensor::GetValue(ObjectSyntax_t * objectSyntax)
-{
-int handle = users.OpenSearch();
-if (!handle)
- return false;
-
-USER_PTR user;
-size_t count = 0;
-while (!users.SearchNext(handle, &user))
- {
- if (user->GetProperty().cash < 0)
- ++count;
- }
-
-users.CloseSearch(handle);
-
-Int2OS(objectSyntax, count);
-return true;
-}
-
-bool DisabledDetailStatsUsersSensor::GetValue(ObjectSyntax_t * objectSyntax)
-{
-int handle = users.OpenSearch();
-if (!handle)
- return false;
-
-USER_PTR user;
-size_t count = 0;
-while (!users.SearchNext(handle, &user))
- {
- if (user->GetProperty().disabledDetailStat)
- ++count;
- }
-
-users.CloseSearch(handle);
-
-Int2OS(objectSyntax, count);
-return true;
-}
-
-bool DisabledUsersSensor::GetValue(ObjectSyntax_t * objectSyntax)
-{
-int handle = users.OpenSearch();
-if (!handle)
- return false;
-
-USER_PTR user;
-size_t count = 0;
-while (!users.SearchNext(handle, &user))
- {
- if (user->GetProperty().disabled)
- ++count;
- }
-
-users.CloseSearch(handle);
-
-Int2OS(objectSyntax, count);
-return true;
-}
-
-bool PassiveUsersSensor::GetValue(ObjectSyntax_t * objectSyntax)
-{
-int handle = users.OpenSearch();
-if (!handle)
- return false;
-
-USER_PTR user;
-size_t count = 0;
-while (!users.SearchNext(handle, &user))
- {
- if (user->GetProperty().passive)
- ++count;
- }
-
-users.CloseSearch(handle);
-
-Int2OS(objectSyntax, count);
-return true;
-}
-
-bool CreditUsersSensor::GetValue(ObjectSyntax_t * objectSyntax)
-{
-int handle = users.OpenSearch();
-if (!handle)
- return false;
-
-USER_PTR user;
-size_t count = 0;
-while (!users.SearchNext(handle, &user))
- {
- if (user->GetProperty().credit > 0)
- ++count;
- }
-
-users.CloseSearch(handle);
-
-Int2OS(objectSyntax, count);
-return true;
-}
-
-bool FreeMbUsersSensor::GetValue(ObjectSyntax_t * objectSyntax)
-{
-int handle = users.OpenSearch();
-if (!handle)
- return false;
-
-USER_PTR user;
-size_t count = 0;
-while (!users.SearchNext(handle, &user))
- {
- if (user->GetProperty().freeMb > 0)
- ++count;
- }
-
-users.CloseSearch(handle);
-
-Int2OS(objectSyntax, count);
-return true;
-}
+++ /dev/null
-#ifndef __SENSORS_H__
-#define __SENSORS_H__
-
-#include <string>
-#include <map>
-
-#include "stg/users.h"
-#include "stg/tariffs.h"
-
-#include "asn1/ObjectSyntax.h"
-
-class Sensor {
- public:
- virtual bool GetValue(ObjectSyntax_t * objectSyntax) = 0;
-};
-
-typedef std::map<std::string, Sensor *> Sensors;
-
-void Int2OS(ObjectSyntax_t * dst, long src);
-
-class TotalUsersSensor : public Sensor {
- public:
- TotalUsersSensor(const USERS & u)
- : users(u)
- {}
- virtual ~TotalUsersSensor() {}
-
- bool GetValue(ObjectSyntax_t * objectSyntax)
- {
- Int2OS(objectSyntax, users.GetUserNum());
- return true;
- }
-
- private:
- const USERS & users;
-};
-
-class ConnectedUsersSensor : public Sensor {
- public:
- ConnectedUsersSensor(USERS & u)
- : users(u)
- {}
- virtual ~ConnectedUsersSensor() {}
-
- bool GetValue(ObjectSyntax_t * objectSyntax);
-
- private:
- USERS & users;
-};
-
-class AuthorizedUsersSensor : public Sensor {
- public:
- AuthorizedUsersSensor(USERS & u)
- : users(u)
- {}
- virtual ~AuthorizedUsersSensor() {}
-
- bool GetValue(ObjectSyntax_t * objectSyntax);
-
- private:
- USERS & users;
-};
-
-class AlwaysOnlineUsersSensor : public Sensor {
- public:
- AlwaysOnlineUsersSensor(USERS & u)
- : users(u)
- {}
- virtual ~AlwaysOnlineUsersSensor() {}
-
- bool GetValue(ObjectSyntax_t * objectSyntax);
-
- private:
- USERS & users;
-};
-
-class NoCashUsersSensor : public Sensor {
- public:
- NoCashUsersSensor(USERS & u)
- : users(u)
- {}
- virtual ~NoCashUsersSensor() {}
-
- bool GetValue(ObjectSyntax_t * objectSyntax);
-
- private:
- USERS & users;
-};
-
-class DisabledDetailStatsUsersSensor : public Sensor {
- public:
- DisabledDetailStatsUsersSensor(USERS & u)
- : users(u)
- {}
- virtual ~DisabledDetailStatsUsersSensor() {}
-
- bool GetValue(ObjectSyntax_t * objectSyntax);
-
- private:
- USERS & users;
-};
-
-class DisabledUsersSensor : public Sensor {
- public:
- DisabledUsersSensor(USERS & u)
- : users(u)
- {}
- virtual ~DisabledUsersSensor() {}
-
- bool GetValue(ObjectSyntax_t * objectSyntax);
-
- private:
- USERS & users;
-};
-
-class PassiveUsersSensor : public Sensor {
- public:
- PassiveUsersSensor(USERS & u)
- : users(u)
- {}
- virtual ~PassiveUsersSensor() {}
-
- bool GetValue(ObjectSyntax_t * objectSyntax);
-
- private:
- USERS & users;
-};
-
-class CreditUsersSensor : public Sensor {
- public:
- CreditUsersSensor(USERS & u)
- : users(u)
- {}
- virtual ~CreditUsersSensor() {}
-
- bool GetValue(ObjectSyntax_t * objectSyntax);
-
- private:
- USERS & users;
-};
-
-class FreeMbUsersSensor : public Sensor {
- public:
- FreeMbUsersSensor(USERS & u)
- : users(u)
- {}
- virtual ~FreeMbUsersSensor() {}
-
- bool GetValue(ObjectSyntax_t * objectSyntax);
-
- private:
- USERS & users;
-};
-
-class TotalTariffsSensor : public Sensor {
- public:
- TotalTariffsSensor(const TARIFFS & t)
- : tariffs(t)
- {}
- virtual ~TotalTariffsSensor() {}
-
- bool GetValue(ObjectSyntax_t * objectSyntax)
- {
- Int2OS(objectSyntax, tariffs.GetTariffsNum());
- return true;
- }
-
- private:
- const TARIFFS & tariffs;
-};
-
-#endif
+++ /dev/null
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <arpa/inet.h>
-
-#include <cstring>
-#include <cerrno>
-#include <ctime>
-#include <csignal>
-
-#include <vector>
-#include <algorithm>
-
-#include "asn1/OpenPDU.h"
-#include "asn1/ClosePDU.h"
-#include "asn1/RReqPDU.h"
-#include "asn1/GetRequest-PDU.h"
-#include "asn1/GetResponse-PDU.h"
-#include "asn1/VarBindList.h"
-#include "asn1/VarBind.h"
-#include "asn1/OBJECT_IDENTIFIER.h"
-#include "asn1/ber_decoder.h"
-#include "asn1/der_encoder.h"
-
-#include "snmp.h"
-#include "stg/common.h"
-
-bool WaitPackets(int sd);
-
-std::string OI2String(OBJECT_IDENTIFIER_t * oi)
-{
-std::string res;
-
-int arcs[1024];
-int count = OBJECT_IDENTIFIER_get_arcs(oi, arcs, sizeof(arcs[0]), 1024);
-
-if (count > 1024)
- return "";
-
-for (int i = 0; i < count; ++i)
- {
- res += ".";
- std::string arc;
- strprintf(&arc, "%d", arcs[i]);
- res += arc;
- }
-
-return res;
-}
-
-bool String2OI(const std::string & str, OBJECT_IDENTIFIER_t * oi)
-{
-size_t left = 0, pos = 0, arcPos = 0;
-int arcs[1024];
-pos = str.find_first_of('.', left);
-if (pos == 0)
- {
- left = 1;
- pos = str.find_first_of('.', left);
- }
-while (pos != std::string::npos)
- {
- int arc = 0;
- if (str2x(str.substr(left, left - pos), arc))
- {
- return false;
- }
- arcs[arcPos++] = arc;
- left = pos + 1;
- pos = str.find_first_of('.', left);
- }
-if (left < str.length())
- {
- int arc = 0;
- if (str2x(str.substr(left, left - pos), arc))
- {
- return false;
- }
- arcs[arcPos++] = arc;
- }
-printfd(__FILE__, "String2OI() - arcPos: %d\n", arcPos);
-OBJECT_IDENTIFIER_set_arcs(oi, arcs, sizeof(arcs[0]), arcPos);
-return true;
-}
-
-class SNMP_AGENT_CREATOR
-{
-private:
- SNMP_AGENT * snmpAgent;
-
-public:
- SNMP_AGENT_CREATOR()
- : snmpAgent(new SNMP_AGENT())
- {
- };
- ~SNMP_AGENT_CREATOR()
- {
- printfd(__FILE__, "SNMP_AGENT_CREATOR::~SNMP_AGENT_CREATOR()\n");
- delete snmpAgent;
- };
-
- SNMP_AGENT * GetPlugin()
- {
- return snmpAgent;
- };
-};
-
-SNMP_AGENT_CREATOR sac;
-
-PLUGIN * GetPlugin()
-{
-return sac.GetPlugin();
-}
-
-int SendOpenPDU(int fd)
-{
-const char * description = "Stg SNMP Agent";
-//int oid[] = {1, 3, 6, 1, 4, 1, 9363, 1, 5, 2, 1, 1};
-asn_enc_rval_t error;
-OpenPDU_t msg;
-
-memset(&msg, 0, sizeof(msg));
-
-msg.present = OpenPDU_PR_simple;
-asn_long2INTEGER(&msg.choice.simple.version, SimpleOpen__version_version_1);
-/*OBJECT_IDENTIFIER_set_arcs(&msg.choice.simple.identity,
- oid,
- sizeof(oid[0]),
- 7);*/
-if (!String2OI(".1.3.6.1.4.1.9363", &msg.choice.simple.identity))
- {
- printfd(__FILE__, "SendOpenPDU() - failed to convert string to OBJECT_IDENTIFIER\n");
- return -1;
- }
-OCTET_STRING_fromString(&msg.choice.simple.description,
- description);
-OCTET_STRING_fromString(&msg.choice.simple.password,
- "");
-
-char buffer[1024];
-error = der_encode_to_buffer(&asn_DEF_OpenPDU, &msg, buffer, sizeof(buffer));
-
-if (error.encoded == -1)
- {
- printfd(__FILE__, "Could not encode OpenPDU (at %s)\n",
- error.failed_type ? error.failed_type->name : "unknown");
- return -1;
- }
-else
- {
- write(fd, buffer, error.encoded);
- printfd(__FILE__, "OpenPDU encoded successfully to %d bytes\n", error.encoded);
- }
-return 0;
-}
-
-int SendClosePDU(int fd)
-{
-ClosePDU_t msg;
-
-memset(&msg, 0, sizeof(msg));
-
-asn_long2INTEGER(&msg, ClosePDU_goingDown);
-
-char buffer[1024];
-asn_enc_rval_t error;
-error = der_encode_to_buffer(&asn_DEF_ClosePDU, &msg, buffer, sizeof(buffer));
-
-if (error.encoded == -1)
- {
- printfd(__FILE__, "Could not encode ClosePDU (at %s)\n",
- error.failed_type ? error.failed_type->name : "unknown");
- return -1;
- }
-else
- {
- write(fd, buffer, error.encoded);
- printfd(__FILE__, "ClosePDU encoded successfully\n");
- }
-return 0;
-}
-
-int SendRReqPDU(int fd)
-{
-int oid[] = {1, 3, 6, 1, 4, 1, 9363, 1};
-asn_enc_rval_t error;
-RReqPDU_t msg;
-
-memset(&msg, 0, sizeof(msg));
-
-msg.priority = 0;
-asn_long2INTEGER(&msg.operation, RReqPDU__operation_readOnly);
-OBJECT_IDENTIFIER_set_arcs(&msg.subtree,
- oid,
- sizeof(oid[0]),
- 8);
-
-char buffer[1024];
-error = der_encode_to_buffer(&asn_DEF_RReqPDU, &msg, buffer, sizeof(buffer));
-
-if (error.encoded == -1)
- {
- printfd(__FILE__, "Could not encode RReqPDU (at %s)\n",
- error.failed_type ? error.failed_type->name : "unknown");
- return -1;
- }
-else
- {
- write(fd, buffer, error.encoded);
- printfd(__FILE__, "RReqPDU encoded successfully to %d bytes\n", error.encoded);
- }
-return 0;
-}
-
-int SendGetResponsePDU(int fd, GetResponse_PDU_t * getResponse)
-{
-asn_enc_rval_t error;
-
-char buffer[1024];
-error = der_encode_to_buffer(&asn_DEF_GetResponse_PDU, getResponse, buffer, sizeof(buffer));
-
-if (error.encoded == -1)
- {
- printfd(__FILE__, "Could not encode GetResponsePDU (at %s)\n",
- error.failed_type ? error.failed_type->name : "unknown");
- return -1;
- }
-else
- {
- write(fd, buffer, error.encoded);
- printfd(__FILE__, "GetResponsePDU encoded successfully to %d bytes\n", error.encoded);
- }
-return 0;
-}
-
-int SendGetResponseErrorPDU(int fd, const PDU_t * getRequest, int errorStatus, int errorIndex)
-{
-asn_enc_rval_t error;
-GetResponse_PDU_t msg;
-
-memset(&msg, 0, sizeof(msg));
-
-msg.request_id = getRequest->request_id;
-asn_long2INTEGER(&msg.error_status, errorStatus);
-asn_long2INTEGER(&msg.error_index, errorIndex);
-
-char buffer[1024];
-error = der_encode_to_buffer(&asn_DEF_GetResponse_PDU, &msg, buffer, sizeof(buffer));
-
-if (error.encoded == -1)
- {
- printfd(__FILE__, "Could not encode GetResponsePDU for error (at %s)\n",
- error.failed_type ? error.failed_type->name : "unknown");
- return -1;
- }
-else
- {
- write(fd, buffer, error.encoded);
- printfd(__FILE__, "GetResponsePDU for error encoded successfully to %d bytes\n", error.encoded);
- }
-return 0;
-}
-
-SMUX_PDUs_t * RecvSMUXPDUs(int fd)
-{
-char buffer[1024];
-SMUX_PDUs_t * pdus = NULL;
-
-memset(buffer, 0, sizeof(buffer));
-
-size_t length = read(fd, buffer, sizeof(buffer));
-if (length < 1)
- return NULL;
-asn_dec_rval_t error;
-error = ber_decode(0, &asn_DEF_SMUX_PDUs, (void **)&pdus, buffer, length);
-if(error.code != RC_OK)
- {
- printfd(__FILE__, "Failed to decode PDUs at byte %ld\n",
- (long)error.consumed);
- return NULL;
- }
-return pdus;
-}
-
-int ParseIntInRange(const std::string & str,
- int min,
- int max,
- int * val)
-{
-if (str2x(str.c_str(), *val))
- {
- return -1;
- }
-if (*val < min || *val > max)
- {
- return -1;
- }
-return 0;
-}
-
-SNMP_AGENT_SETTINGS::SNMP_AGENT_SETTINGS()
- : ip(0),
- port(0)
-{}
-
-int SNMP_AGENT_SETTINGS::ParseSettings(const MODULE_SETTINGS & s)
-{
-PARAM_VALUE pv;
-std::vector<PARAM_VALUE>::const_iterator pvi;
-int p;
-///////////////////////////
-pv.param = "Port";
-pvi = std::find(s.moduleParams.begin(), s.moduleParams.end(), pv);
-if (pvi == s.moduleParams.end())
- {
- errorStr = "Parameter \'Port\' not found.";
- printfd(__FILE__, "Parameter 'Port' not found\n");
- return -1;
- }
-if (ParseIntInRange(pvi->value[0], 2, 65535, &p))
- {
- errorStr = "Cannot parse parameter \'Port\': " + errorStr;
- printfd(__FILE__, "Cannot parse parameter 'Port'\n");
- return -1;
- }
-port = p;
-
-pv.param = "Password";
-pvi = std::find(s.moduleParams.begin(), s.moduleParams.end(), pv);
-if (pvi == s.moduleParams.end())
- {
- errorStr = "Parameter \'Password\' not found.";
- printfd(__FILE__, "Parameter 'Password' not found\n");
- password = "";
- }
-else
- {
- password = pvi->value[0];
- }
-
-pv.param = "Server";
-pvi = std::find(s.moduleParams.begin(), s.moduleParams.end(), pv);
-if (pvi == s.moduleParams.end())
- {
- errorStr = "Parameter \'Server\' not found.";
- printfd(__FILE__, "Parameter 'Server' not found\n");
- return -1;
- }
-ip = inet_strington(pvi->value[0]);
-
-return 0;
-}
-
-SNMP_AGENT::SNMP_AGENT()
- : PLUGIN(),
- users(NULL),
- tariffs(NULL),
- running(false),
- stopped(true),
- sock(-1)
-{
-pthread_mutex_init(&mutex, NULL);
-
-smuxHandlers[SMUX_PDUs_PR_close] = &SNMP_AGENT::CloseHandler;
-smuxHandlers[SMUX_PDUs_PR_registerResponse] = &SNMP_AGENT::RegisterResponseHandler;
-smuxHandlers[SMUX_PDUs_PR_pdus] = &SNMP_AGENT::PDUsHandler;
-smuxHandlers[SMUX_PDUs_PR_commitOrRollback] = &SNMP_AGENT::CommitOrRollbackHandler;
-
-pdusHandlers[PDUs_PR_get_request] = &SNMP_AGENT::GetRequestHandler;
-pdusHandlers[PDUs_PR_get_next_request] = &SNMP_AGENT::GetNextRequestHandler;
-pdusHandlers[PDUs_PR_set_request] = &SNMP_AGENT::SetRequestHandler;
-}
-
-SNMP_AGENT::~SNMP_AGENT()
-{
-Sensors::iterator it;
-for (it = sensors.begin(); it != sensors.end(); ++it)
- delete it->second;
-printfd(__FILE__, "SNMP_AGENT::~SNMP_AGENT()\n");
-pthread_mutex_destroy(&mutex);
-}
-
-int SNMP_AGENT::ParseSettings()
-{
-return snmpAgentSettings.ParseSettings(settings);
-}
-
-int SNMP_AGENT::Start()
-{
-if (PrepareNet())
- return -1;
-
-// Users
-sensors[".1.3.6.1.4.1.9363.1.1.1"] = new TotalUsersSensor(*users);
-sensors[".1.3.6.1.4.1.9363.1.1.2"] = new ConnectedUsersSensor(*users);
-sensors[".1.3.6.1.4.1.9363.1.1.3"] = new AuthorizedUsersSensor(*users);
-sensors[".1.3.6.1.4.1.9363.1.1.4"] = new AlwaysOnlineUsersSensor(*users);
-sensors[".1.3.6.1.4.1.9363.1.1.5"] = new NoCashUsersSensor(*users);
-sensors[".1.3.6.1.4.1.9363.1.1.7"] = new DisabledDetailStatsUsersSensor(*users);
-sensors[".1.3.6.1.4.1.9363.1.1.8"] = new DisabledUsersSensor(*users);
-sensors[".1.3.6.1.4.1.9363.1.1.9"] = new PassiveUsersSensor(*users);
-sensors[".1.3.6.1.4.1.9363.1.1.10"] = new CreditUsersSensor(*users);
-sensors[".1.3.6.1.4.1.9363.1.1.11"] = new FreeMbUsersSensor(*users);
-// Tariffs
-sensors[".1.3.6.1.4.1.9363.1.2.1"] = new TotalTariffsSensor(*tariffs);
-
-if (!running)
- {
- if (pthread_create(&thread, NULL, Runner, this))
- {
- errorStr = "Cannot create thread.";
- printfd(__FILE__, "Cannot create thread\n");
- return -1;
- }
- }
-
-return 0;
-}
-
-int SNMP_AGENT::Stop()
-{
-printfd(__FILE__, "SNMP_AGENT::Stop() - Before\n");
-running = false;
-
-if (!stopped)
- {
- //5 seconds to thread stops itself
- for (int i = 0; i < 25 && !stopped; i++)
- {
- struct timespec ts = {0, 200000000};
- nanosleep(&ts, NULL);
- }
-
- //after 5 seconds waiting thread still running. now killing it
- if (!stopped)
- {
- printfd(__FILE__, "SNMP_AGENT::Stop() - failed to stop thread, killing it\n");
- if (pthread_kill(thread, SIGINT))
- {
- errorStr = "Cannot kill thread.";
- printfd(__FILE__, "SNMP_AGENT::Stop() - Cannot kill thread\n");
- return -1;
- }
- printfd(__FILE__, "SNMP_AGENT::Stop() - killed Run\n");
- }
- }
-
-pthread_join(thread, NULL);
-
-close(sock);
-
-printfd(__FILE__, "SNMP_AGENT::Stop() - After\n");
-return 0;
-}
-
-void * SNMP_AGENT::Runner(void * d)
-{
-SNMP_AGENT * snmpAgent = static_cast<SNMP_AGENT *>(d);
-
-snmpAgent->Run();
-
-return NULL;
-}
-
-void SNMP_AGENT::Run()
-{
-SendOpenPDU(sock);
-SendRReqPDU(sock);
-running = true;
-stopped = false;
-printfd(__FILE__, "SNMP_AGENT::Run() - Before\n");
-while(running)
- {
- if (WaitPackets(sock))
- {
- SMUX_PDUs_t * pdus = RecvSMUXPDUs(sock);
- if (pdus)
- DispatchPDUs(pdus);
- }
- if (!running)
- break;
- }
-printfd(__FILE__, "SNMP_AGENT::Run() - After\n");
-SendClosePDU(sock);
-stopped = true;
-}
-
-bool SNMP_AGENT::PrepareNet()
-{
-sock = socket(AF_INET, SOCK_STREAM, 0);
-
-if (sock < 0)
- {
- errorStr = "Cannot create socket.";
- printfd(__FILE__, "Cannot create socket\n");
- return true;
- }
-
-struct sockaddr_in addr;
-
-addr.sin_family = AF_INET;
-addr.sin_port = htons(snmpAgentSettings.GetPort());
-addr.sin_addr.s_addr = snmpAgentSettings.GetIP();
-
-if (connect(sock, reinterpret_cast<struct sockaddr *>(&addr), sizeof(addr)))
- {
- errorStr = "Cannot connect.";
- printfd(__FILE__, "Cannot connect. Message: '%s'\n", strerror(errno));
- return true;
- }
-
-return false;
-}
-
-bool WaitPackets(int sd)
-{
-fd_set rfds;
-FD_ZERO(&rfds);
-FD_SET(sd, &rfds);
-
-struct timeval tv;
-tv.tv_sec = 0;
-tv.tv_usec = 500000;
-
-int res = select(sd + 1, &rfds, NULL, NULL, &tv);
-if (res == -1) // Error
- {
- if (errno != EINTR)
- {
- printfd(__FILE__, "Error on select: '%s'\n", strerror(errno));
- }
- return false;
- }
-
-if (res == 0) // Timeout
- {
- return false;
- }
-
-return true;
-}
-
-bool SNMP_AGENT::DispatchPDUs(const SMUX_PDUs_t * pdus)
-{
-SMUXHandlers::iterator it;
-it = smuxHandlers.find(pdus->present);
-if (it != smuxHandlers.end())
- {
- return (this->*(it->second))(pdus);
- }
-else
- {
- switch (pdus->present)
- {
- case SMUX_PDUs_PR_NOTHING:
- printfd(__FILE__, "PDUs: nothing\n");
- break;
- case SMUX_PDUs_PR_open:
- printfd(__FILE__, "PDUs: open\n");
- break;
- case SMUX_PDUs_PR_registerRequest:
- printfd(__FILE__, "PDUs: registerRequest\n");
- break;
- default:
- printfd(__FILE__, "PDUs: undefined\n");
- }
- asn_fprint(stderr, &asn_DEF_SMUX_PDUs, pdus);
- }
-return false;
-}
-
-bool SNMP_AGENT::CloseHandler(const SMUX_PDUs_t * pdus)
-{
-printfd(__FILE__, "SNMP_AGENT::CloseHandler()\n");
-asn_fprint(stderr, &asn_DEF_SMUX_PDUs, pdus);
-return false;
-}
-
-bool SNMP_AGENT::RegisterResponseHandler(const SMUX_PDUs_t * pdus)
-{
-printfd(__FILE__, "SNMP_AGENT::RegisterResponseHandler()\n");
-asn_fprint(stderr, &asn_DEF_SMUX_PDUs, pdus);
-return false;
-}
-
-bool SNMP_AGENT::PDUsHandler(const SMUX_PDUs_t * pdus)
-{
-printfd(__FILE__, "SNMP_AGENT::PDUsHandler()\n");
-asn_fprint(stderr, &asn_DEF_SMUX_PDUs, pdus);
-PDUsHandlers::iterator it;
-it = pdusHandlers.find(pdus->choice.pdus.present);
-if (it != pdusHandlers.end())
- {
- return (this->*(it->second))(&pdus->choice.pdus);
- }
-else
- {
- switch (pdus->present)
- {
- case PDUs_PR_NOTHING:
- printfd(__FILE__, "SNMP_AGENT::PDUsHandler() - nothing\n");
- break;
- case PDUs_PR_get_response:
- printfd(__FILE__, "SNMP_AGENT::PDUsHandler() - get response\n");
- break;
- case PDUs_PR_trap:
- printfd(__FILE__, "SNMP_AGENT::PDUsHandler() - trap\n");
- break;
- default:
- printfd(__FILE__, "SNMP_AGENT::PDUsHandler() - undefined\n");
- }
- }
-return false;
-}
-
-bool SNMP_AGENT::CommitOrRollbackHandler(const SMUX_PDUs_t * pdus)
-{
-printfd(__FILE__, "SNMP_AGENT::CommitOrRollbackHandler()\n");
-asn_fprint(stderr, &asn_DEF_SMUX_PDUs, pdus);
-return false;
-}
-
-bool SNMP_AGENT::GetRequestHandler(const PDUs_t * pdus)
-{
-printfd(__FILE__, "SNMP_AGENT::GetRequestHandler()\n");
-asn_fprint(stderr, &asn_DEF_PDUs, pdus);
-const GetRequest_PDU_t * getRequest = &pdus->choice.get_request;
-GetResponse_PDU_t msg;
-VarBindList_t * varBindList = &msg.variable_bindings;
-memset(&msg, 0, sizeof(msg));
-
-msg.request_id = getRequest->request_id;
-asn_long2INTEGER(&msg.error_status, 0);
-asn_long2INTEGER(&msg.error_index, 0);
-
-const VarBindList_t * vbl = &getRequest->variable_bindings;
-for (int i = 0; i < vbl->list.count; ++i)
- {
- VarBind_t * vb = getRequest->variable_bindings.list.array[i];
- Sensors::iterator it;
- it = sensors.find(OI2String(&vb->name));
- if (it == sensors.end())
- {
- SendGetResponseErrorPDU(sock, getRequest, PDU__error_status_noSuchName, i);
- return true;
- }
-
- VarBind_t newVb;
- memset(&newVb, 0, sizeof(newVb));
-
- newVb.name = vb->name;
- it->second->GetValue(&newVb.value);
-
- ASN_SEQUENCE_ADD(varBindList, &newVb);
- }
-
-SendGetResponsePDU(sock, &msg);
-asn_fprint(stderr, &asn_DEF_PDU, &msg);
-return false;
-}
-
-bool SNMP_AGENT::GetNextRequestHandler(const PDUs_t * pdus)
-{
-printfd(__FILE__, "SNMP_AGENT::GetNextRequestHandler()\n");
-asn_fprint(stderr, &asn_DEF_PDUs, pdus);
-return false;
-}
-
-bool SNMP_AGENT::SetRequestHandler(const PDUs_t * pdus)
-{
-printfd(__FILE__, "SNMP_AGENT::SetRequestHandler()\n");
-asn_fprint(stderr, &asn_DEF_PDUs, pdus);
-SendGetResponseErrorPDU(sock, &pdus->choice.set_request, PDU__error_status_readOnly, 0);
-return false;
-}
-
+++ /dev/null
-#ifndef __SNMP_AGENT_H__
-#define __SNMP_AGENT_H__
-
-#include <pthread.h>
-
-#include <string>
-#include <map>
-
-#include "asn1/SMUX-PDUs.h"
-#include "asn1/ObjectSyntax.h"
-
-#include "stg/os_int.h"
-#include "stg/plugin.h"
-#include "stg/module_settings.h"
-#include "stg/users.h"
-#include "stg/tariffs.h"
-
-#include "sensors.h"
-
-extern "C" PLUGIN * GetPlugin();
-
-class USER;
-class SETTINGS;
-class SNMP_AGENT;
-
-typedef bool (SNMP_AGENT::*SMUXPacketHandler)(const SMUX_PDUs_t * pdus);
-typedef bool (SNMP_AGENT::*PDUsHandler)(const PDUs_t * pdus);
-typedef std::map<SMUX_PDUs_PR, SMUXPacketHandler> SMUXHandlers;
-typedef std::map<PDUs_PR, PDUsHandler> PDUsHandlers;
-//-----------------------------------------------------------------------------
-class SNMP_AGENT_SETTINGS {
-public:
- SNMP_AGENT_SETTINGS();
- virtual ~SNMP_AGENT_SETTINGS() {}
- const std::string & GetStrError() const { return errorStr; }
- int ParseSettings(const MODULE_SETTINGS & s);
-
- uint32_t GetIP() const { return ip; }
- uint16_t GetPort() const { return port; }
- const std::string GetPassword() const { return password; }
-
-private:
- mutable std::string errorStr;
-
- uint32_t ip;
- uint16_t port;
- std::string password;
-};
-//-----------------------------------------------------------------------------
-class SNMP_AGENT : public PLUGIN {
-public:
- SNMP_AGENT();
- virtual ~SNMP_AGENT();
-
- void SetUsers(USERS * u) { users = u; }
- void SetTariffs(TARIFFS * t) { tariffs = t; }
- void SetAdmins(ADMINS *) {}
- void SetTraffcounter(TRAFFCOUNTER *) {}
- void SetStore(STORE *) {}
- void SetStgSettings(const SETTINGS *) {}
- void SetSettings(const MODULE_SETTINGS & s) { settings = s; }
- int ParseSettings();
-
- int Start();
- int Stop();
- int Reload() { return 0; }
- bool IsRunning() { return running && !stopped; }
-
- const std::string & GetStrError() const { return errorStr; }
- const std::string GetVersion() const { return "Stg SNMP Agent 1.0"; }
- uint16_t GetStartPosition() const { return 100; }
- uint16_t GetStopPosition() const { return 100; }
-
-private:
- static void * Runner(void * d);
- void Run();
- bool PrepareNet();
-
- bool DispatchPDUs(const SMUX_PDUs_t * pdus);
-
- bool CloseHandler(const SMUX_PDUs_t * pdus);
- bool RegisterResponseHandler(const SMUX_PDUs_t * pdus);
- bool PDUsHandler(const SMUX_PDUs_t * pdus);
- bool CommitOrRollbackHandler(const SMUX_PDUs_t * pdus);
-
- bool GetRequestHandler(const PDUs_t * pdus);
- bool GetNextRequestHandler(const PDUs_t * pdus);
- bool SetRequestHandler(const PDUs_t * pdus);
-
- USERS * users;
- TARIFFS * tariffs;
-
- mutable std::string errorStr;
- SNMP_AGENT_SETTINGS snmpAgentSettings;
- MODULE_SETTINGS settings;
-
- pthread_t thread;
- pthread_mutex_t mutex;
- bool running;
- bool stopped;
-
- int sock;
-
- SMUXHandlers smuxHandlers;
- PDUsHandlers pdusHandlers;
- Sensors sensors;
-};
-//-----------------------------------------------------------------------------
-
-extern "C" PLUGIN * GetPlugin();
-
-#endif
USERSTAT();
~USERSTAT();
- virtual void SetUsers(USERS * u) { users = u; };
- virtual void SetTariffs(TARIFFS * t) {};
- virtual void SetAdmins(ADMINS * a) {};
- virtual void SetTraffcounter(TRAFFCOUNTER * tc) {};
- virtual void SetStore(BASE_STORE * st) { store = st; };
- virtual void SetStgSettings(const SETTINGS * s) {};
- virtual void SetSettings(const MODULE_SETTINGS & s) { settings = s; };
+ virtual void SetUsers(USERS * u) { users = u; }
+ virtual void SetStore(BASE_STORE * st) { store = st; }
+ virtual void SetSettings(const MODULE_SETTINGS & s) { settings = s; }
virtual int ParseSettings();
virtual int Start();
virtual int Stop();
- virtual bool IsRunning() { return isRunning; };
- virtual const string & GetStrError() const { return errorStr; };
- virtual const string GetVersion() const { return version; };
- virtual uint16_t GetStartPosition() const { return 0; };
- virtual uint16_t GetStopPosition() const { return 0; };
+ virtual bool IsRunning() { return isRunning; }
+ virtual const string & GetStrError() const { return errorStr; }
+ virtual const string GetVersion() const { return version; }
+ virtual uint16_t GetStartPosition() const { return 0; }
+ virtual uint16_t GetStopPosition() const { return 0; }
private:
struct IsDone : public unary_function<DataThread, bool>
{
- bool operator()(const DataThread & info) { return info.IsDone(); };
+ bool operator()(const DataThread & info) { return info.IsDone(); }
};
struct ToLower : public unary_function<char, char>
{
SRCS = ./file_store.cpp
-STGLIBS = -lstgconffiles -lstgcommon -lstglocker -lstgcrypto
+STGLIBS = conffiles \
+ common \
+ locker \
+ logger \
+ crypto
include ../../Makefile.in
#include "stg/blowfish.h"
#include "stg/logger.h"
#include "stg/locker.h"
+#include "stg/plugin_creator.h"
#include "file_store.h"
#define DELETED_USERS_DIR "deleted_users"
const int pt_mega = 1024 * 1024;
//-----------------------------------------------------------------------------
-class BAK_FILE
-{
-public:
-
- //-------------------------------------------------------------------------
- BAK_FILE(const string & fileName, bool removeBak)
- : f(NULL),
- removeBak(false)
- {
- bakSuccessed = false;
- BAK_FILE::removeBak = removeBak;
- fileNameBak = fileName + ".bak";
- if (rename(fileName.c_str(), fileNameBak.c_str()))
- {
- printfd(__FILE__, "BAK_FILE::BAK_FILE - rename failed. Message: '%s'\n", strerror(errno));
- }
- else
- {
- bakSuccessed = true;
- }
-
- }
- //-------------------------------------------------------------------------
- ~BAK_FILE()
- {
- if(bakSuccessed && removeBak)
- {
- if (unlink(fileNameBak.c_str()))
- {
- printfd(__FILE__, "BAK_FILE::~BAK_FILE - unlink failed. Message: '%s'\n", strerror(errno));
- }
- }
- }
- //-------------------------------------------------------------------------
-
-private:
- FILE * f;
- bool bakSuccessed;
- string fileNameBak;
- bool removeBak;
-};
-//-----------------------------------------------------------------------------
-class FILES_STORE_CREATOR
-{
-private:
- FILES_STORE * fs;
-
-public:
- FILES_STORE_CREATOR()
- : fs(new FILES_STORE())
- {
- };
- ~FILES_STORE_CREATOR()
- {
- delete fs;
- };
-
- FILES_STORE * GetStore()
- {
- return fs;
- };
-};
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-FILES_STORE_CREATOR fsc;
+PLUGIN_CREATOR<FILES_STORE> fsc;
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
STORE * GetStore()
{
-return fsc.GetStore();
+return fsc.GetPlugin();
}
//-----------------------------------------------------------------------------
FILES_STORE_SETTINGS::FILES_STORE_SETTINGS()
: settings(NULL),
+ errorStr(),
+ workDir(),
+ usersDir(),
+ adminsDir(),
+ tariffsDir(),
+ statMode(0),
+ statUID(0),
+ statGID(0),
+ confMode(0),
+ confUID(0),
+ confGID(0),
+ userLogMode(0),
+ userLogUID(0),
+ userLogGID(0),
removeBak(true),
readBak(true)
{
}
//-----------------------------------------------------------------------------
-FILES_STORE_SETTINGS::~FILES_STORE_SETTINGS()
-{
-}
-//-----------------------------------------------------------------------------
int FILES_STORE_SETTINGS::ParseOwner(const vector<PARAM_VALUE> & moduleParams, const string & owner, uid_t * uid)
{
PARAM_VALUE pv;
return 0;
}
//-----------------------------------------------------------------------------
-string FILES_STORE_SETTINGS::GetWorkDir() const
-{
-return workDir;
-}
-//-----------------------------------------------------------------------------
-string FILES_STORE_SETTINGS::GetUsersDir() const
-{
-return usersDir;
-}
-//-----------------------------------------------------------------------------
-string FILES_STORE_SETTINGS::GetAdminsDir() const
-{
-return adminsDir;
-}
-//-----------------------------------------------------------------------------
-string FILES_STORE_SETTINGS::GetTariffsDir() const
-{
-return tariffsDir;
-}
-//-----------------------------------------------------------------------------
-mode_t FILES_STORE_SETTINGS::GetStatMode() const
-{
-return statMode;
-}
-//-----------------------------------------------------------------------------
mode_t FILES_STORE_SETTINGS::GetStatModeDir() const
{
mode_t mode = statMode;
return mode;
}
//-----------------------------------------------------------------------------
-uid_t FILES_STORE_SETTINGS::GetStatUID() const
-{
-return statUID;
-}
-//-----------------------------------------------------------------------------
-gid_t FILES_STORE_SETTINGS::GetStatGID() const
-{
-return statGID;
-}
-//-----------------------------------------------------------------------------
-mode_t FILES_STORE_SETTINGS::GetConfMode() const
-{
-return confMode;
-}
-//-----------------------------------------------------------------------------
mode_t FILES_STORE_SETTINGS::GetConfModeDir() const
{
mode_t mode = confMode;
return mode;
}
//-----------------------------------------------------------------------------
-uid_t FILES_STORE_SETTINGS::GetConfUID() const
-{
-return confUID;
-}
-//-----------------------------------------------------------------------------
-gid_t FILES_STORE_SETTINGS::GetConfGID() const
-{
-return confGID;
-}
-//-----------------------------------------------------------------------------
-mode_t FILES_STORE_SETTINGS::GetLogMode() const
-{
-return userLogMode;
-}
-//-----------------------------------------------------------------------------
-uid_t FILES_STORE_SETTINGS::GetLogUID() const
-{
-return userLogUID;
-}
-//-----------------------------------------------------------------------------
-gid_t FILES_STORE_SETTINGS::GetLogGID() const
-{
-return userLogGID;
-}
-//-----------------------------------------------------------------------------
-bool FILES_STORE_SETTINGS::GetRemoveBak() const
-{
-return removeBak;
-}
-//-----------------------------------------------------------------------------
-bool FILES_STORE_SETTINGS::GetReadBak() const
-{
-return readBak;
-}
-//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
FILES_STORE::FILES_STORE()
+ : errorStr(),
+ version("file_store v.1.04"),
+ storeSettings(),
+ settings(),
+ mutex()
{
-version = "file_store v.1.04";
-
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&mutex, &attr);
};
//-----------------------------------------------------------------------------
-FILES_STORE::~FILES_STORE()
-{
-
-};
-//-----------------------------------------------------------------------------
-void FILES_STORE::SetSettings(const MODULE_SETTINGS & s)
-{
-settings = s;
-}
-//-----------------------------------------------------------------------------
int FILES_STORE::ParseSettings()
{
int ret = storeSettings.ParseSettings(settings);
return ret;
}
//-----------------------------------------------------------------------------
-const string & FILES_STORE::GetStrError() const
-{
-STG_LOCKER lock(&mutex, __FILE__, __LINE__);
-return errorStr;
-}
-//-----------------------------------------------------------------------------
-const string & FILES_STORE::GetVersion() const
-{
-return version;
-}
-//-----------------------------------------------------------------------------
int FILES_STORE::GetUsersList(vector<string> * userList) const
{
vector<string> files;
errorStr += strerror(errno);
errorStr += "'";
printfd(__FILE__, "FILES_STORE::RemoveDir() - unlink failed. Message: '%s'\n", strerror(errno));
+ closedir(d);
return -1;
}
}
{
if (RemoveDir(str.c_str()))
{
+ closedir(d);
return -1;
}
printfd(__FILE__, "FILES_STORE::AddUser - fopen failed. Message: '%s'\n", strerror(errno));
return -1;
}
-/*f = fopen(fileName.c_str(), "wt");
-if (f)
- {
- if (fprintf(f, "\n") < 0)
- {
- STG_LOCKER lock(&mutex, __FILE__, __LINE__);
- errorStr = "fprintf failed. Message: '";
- errorStr += strerror(errno);
- errorStr += "'";
- printfd(__FILE__, "FILES_STORE::AddUser - fprintf failed. Message: '%s'\n", strerror(errno));
- return -1;
- }
- fclose(f);
- }
-else
- {
- STG_LOCKER lock(&mutex, __FILE__, __LINE__);
- errorStr = "Cannot create file \"" + fileName + "\'";
- printfd(__FILE__, "FILES_STORE::AddUser - fopen failed. Message: '%s'\n", strerror(errno));
- return -1;
- }*/
strprintf(&fileName, "%s%s/stat", storeSettings.GetUsersDir().c_str(), login.c_str());
if (Touch(fileName))
printfd(__FILE__, "FILES_STORE::AddUser - fopen failed. Message: '%s'\n", strerror(errno));
return -1;
}
-/*f = fopen(fileName.c_str(), "wt");
-if (f)
- {
- if (fprintf(f, "\n") < 0)
- {
- STG_LOCKER lock(&mutex, __FILE__, __LINE__);
- errorStr = "fprintf failed. Message: '";
- errorStr += strerror(errno);
- errorStr += "'";
- printfd(__FILE__, "FILES_STORE::AddUser - fprintf failed. Message: '%s'\n", strerror(errno));
- return -1;
- }
- fclose(f);
- }
-else
- {
- STG_LOCKER lock(&mutex, __FILE__, __LINE__);
- errorStr = "Cannot create file \"" + fileName + "\'";
- printfd(__FILE__, "FILES_STORE::AddUser - fopen failed. Message: '%s'\n", strerror(errno));
- return -1;
- }*/
return 0;
}
//-----------------------------------------------------------------------------
string fileName;
fileName = storeSettings.GetUsersDir() + "/" + login + "/conf";
-//BAK_FILE bakFile(fileName, storeSettings.GetRemoveBak());
-
CONFIGFILE cfstat(fileName, true);
int e = cfstat.Error();
string fileName;
fileName = storeSettings.GetUsersDir() + "/" + login + "/stat";
-//BAK_FILE bakFile(fileName, storeSettings.GetRemoveBak());
-
{
CONFIGFILE cfstat(fileName, true);
int e = cfstat.Error();
for (size_t i = 0; i < DIR_NUM; i++)
{
char dirName[3];
- snprintf(dirName, 3, "U%d", i);
+ snprintf(dirName, 3, "U%llu", (unsigned long long)i);
s.WriteInt(dirName, stat.up[i]); // Classic
s2.WriteInt(dirName, stat.up[i]); // New
- snprintf(dirName, 3, "D%d", i);
+ snprintf(dirName, 3, "D%llu", (unsigned long long)i);
s.WriteInt(dirName, stat.down[i]); // Classic
s2.WriteInt(dirName, stat.down[i]); // New
}
cf.WriteInt("UsrAddDel", ac.priv.userAddDel);
cf.WriteInt("ChgTariff", ac.priv.tariffChg);
cf.WriteInt("ChgAdmin", ac.priv.adminChg);
+ cf.WriteInt("ChgService", ac.priv.serviceChg);
+ cf.WriteInt("ChgCorp", ac.priv.corpChg);
}
return 0;
return -1;
}
+if (cf.ReadInt("ChgService", &a, 0) == 0)
+ ac->priv.serviceChg = a;
+else
+ ac->priv.serviceChg = 0;
+
+if (cf.ReadInt("ChgCorp", &a, 0) == 0)
+ ac->priv.corpChg = a;
+else
+ ac->priv.corpChg = 0;
+
return 0;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
int FILES_STORE::AddMessage(STG_MSG * msg, const string & login) const
{
-//ðÒÏ×ÅÒÉÔØ ÅÓÔØ ÌÉ ÄÉÒÅËÔÏÒÉÑ ÄÌÑ ÓÏÏÂÝÅÎÉÊ. åÓÌÉ ÎÅÔ - ÓÏÚÄÁÔØ.
-//úÁÔÅÍ ÐÏÌÏÖÉÔØ ÓÏÏÂÝÅÎÉÅ Ó ÉÍÅÎÅÍ ÆÁÊÌÁ - ×ÒÅÍÅÎÎOÊ ÍÅÔËÏÊ. úÁÐÉÓÁÔØ ÔÕÄÁ
-//ÔÅËÓÔ É ÐÒÉÏÒÉÔÅÔ.
-
string fn;
string dn;
struct timeval tv;
//-----------------------------------------------------------------------------
int FILES_STORE::EditMessage(const STG_MSG & msg, const string & login) const
{
-//ðÒÏ×ÅÒÉÔØ ÅÓÌÔØ ÌÉ ÄÉÒÅËÔÏÒÉÑ ÄÌÑ ÓÏÏÂÝÅÎÉÊ. åÓÌÉ ÎÅÔ - ÓÏÚÄÁÔØ.
-//úÁÔÅÍ ÐÏÌÏÖÉÔØ ÓÏÏÂÝÅÎÉÅ Ó ÉÍÅÎÅÍ ÆÁÊÌÁ - ×ÒÅÍÅÎÎOÊ ÍÅÔËÏÊ. úÁÐÉÓÁÔØ ÔÕÄÁ
-//ÔÅËÓÔ É ÐÒÉÏÒÉÔÅÔ.
-
string fileName;
FILE * msgFile;
{
string dn(storeSettings.GetUsersDir() + "/" + login + "/messages/");
-//hdrsList->resize(messages.size());
-
if (access(dn.c_str(), F_OK) != 0)
{
return 0;
//-----------------------------------------------------------------------------
int GetFileList(vector<string> * fileList, const string & directory, mode_t mode, const string & ext)
{
-// æÕÎËÃÉÑ ÐÒÏÓÍÁÔÒÉ×ÁÅÔ ÓÏÄÅÒÖÉÍÏÅ ÄÉÒÅËÔÏÒÉÉ
-
DIR * d = opendir(directory.c_str());
if (!d)
class FILES_STORE_SETTINGS {
public:
FILES_STORE_SETTINGS();
- virtual ~FILES_STORE_SETTINGS();
- virtual int ParseSettings(const MODULE_SETTINGS & s);
- virtual const std::string & GetStrError() const;
+ int ParseSettings(const MODULE_SETTINGS & s);
+ const std::string & GetStrError() const;
- std::string GetWorkDir() const;
- std::string GetUsersDir() const;
- std::string GetAdminsDir() const;
- std::string GetTariffsDir() const;
+ std::string GetWorkDir() const { return workDir; }
+ std::string GetUsersDir() const { return usersDir; }
+ std::string GetAdminsDir() const { return adminsDir; }
+ std::string GetTariffsDir() const { return tariffsDir; }
- mode_t GetStatMode() const;
+ mode_t GetStatMode() const { return statMode; }
mode_t GetStatModeDir() const;
- uid_t GetStatUID() const;
- gid_t GetStatGID() const;
+ uid_t GetStatUID() const { return statUID; }
+ gid_t GetStatGID() const { return statGID; }
- mode_t GetConfMode() const;
+ mode_t GetConfMode() const { return confMode; }
mode_t GetConfModeDir() const;
- uid_t GetConfUID() const;
- gid_t GetConfGID() const;
+ uid_t GetConfUID() const { return confUID; }
+ gid_t GetConfGID() const { return confGID; }
- mode_t GetLogMode() const;
- uid_t GetLogUID() const;
- gid_t GetLogGID() const;
+ mode_t GetLogMode() const { return userLogMode; }
+ uid_t GetLogUID() const { return userLogUID; }
+ gid_t GetLogGID() const { return userLogGID; }
- bool GetRemoveBak() const;
- bool GetReadBak() const;
+ bool GetRemoveBak() const { return removeBak; }
+ bool GetReadBak() const { return readBak; }
private:
+ FILES_STORE_SETTINGS(const FILES_STORE_SETTINGS & rvalue);
+ FILES_STORE_SETTINGS & operator=(const FILES_STORE_SETTINGS & rvalue);
+
const MODULE_SETTINGS * settings;
int User2UID(const char * user, uid_t * uid);
class FILES_STORE: public STORE {
public:
FILES_STORE();
- virtual ~FILES_STORE();
- virtual const std::string & GetStrError() const;
+ virtual ~FILES_STORE() {}
+ virtual const std::string & GetStrError() const { return errorStr; }
//User
virtual int GetUsersList(std::vector<std::string> * usersList) const;
virtual int AddService(const std::string &) const { return 0; }
virtual int DelService(const std::string &) const { return 0; }
- virtual void SetSettings(const MODULE_SETTINGS & s);
+ virtual void SetSettings(const MODULE_SETTINGS & s) { settings = s; }
virtual int ParseSettings();
- virtual const std::string & GetVersion() const;
+ virtual const std::string & GetVersion() const { return version; }
private:
+ FILES_STORE(const FILES_STORE & rvalue);
+ FILES_STORE & operator=(const FILES_STORE & rvalue);
+
virtual int RestoreUserStat(USER_STAT * stat, const std::string & login, const std::string & fileName) const;
virtual int RestoreUserConf(USER_CONF * conf, const std::string & login, const std::string & fileName) const;
./firebird_store_users.cpp \
./firebird_store_utils.cpp
-STGLIBS = -libpp -lstgcommon -lstglocker -lstgcrypto
+STGLIBS = ibpp \
+ common \
+ locker \
+ crypto
include ../../Makefile.in
#include <vector>
#include <algorithm>
-using namespace std;
-
-#include "firebird_store.h"
#include "stg/ibpp.h"
+#include "stg/plugin_creator.h"
+#include "firebird_store.h"
-class FIREBIRD_STORE_CREATOR
-{
-public:
- FIREBIRD_STORE_CREATOR()
- : frb(new FIREBIRD_STORE())
- {
- };
- ~FIREBIRD_STORE_CREATOR()
- {
- delete frb;
- };
- FIREBIRD_STORE * GetStore() { return frb; };
-private:
- FIREBIRD_STORE * frb;
-} frsc;
+using namespace std;
+PLUGIN_CREATOR<FIREBIRD_STORE> frsc;
//-----------------------------------------------------------------------------
STORE * GetStore()
{
-return frsc.GetStore();
+return frsc.GetPlugin();
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
FIREBIRD_STORE::FIREBIRD_STORE()
+ : version("firebird_store v.1.4"),
+ strError(),
+ db_server("localhost"),
+ db_database("/var/stg/stargazer.fdb"),
+ db_user("stg"),
+ db_password("123456"),
+ settings(),
+ db(),
+ mutex(),
+ til(IBPP::ilConcurrency),
+ tlr(IBPP::lrWait)
{
-db_server = "localhost";
-db_database = "/var/stg/stargazer.fdb";
-db_user = "stg";
-db_password = "123456";
-version = "firebird_store v.1.4";
pthread_mutex_init(&mutex, NULL);
-
-// Advanced settings defaults
-
-til = IBPP::ilConcurrency;
-tlr = IBPP::lrWait;
}
//-----------------------------------------------------------------------------
FIREBIRD_STORE::~FIREBIRD_STORE()
int RestoreService(SERVICE_CONF * sc, const std::string & name) const;
int AddService(const std::string & name) const;
int DelService(const std::string & name) const;
+
private:
+ FIREBIRD_STORE(const FIREBIRD_STORE & rvalue);
+ FIREBIRD_STORE & operator=(const FIREBIRD_STORE & rvalue);
+
std::string version;
mutable std::string strError;
mutable std::string db_server, db_database, db_user, db_password;
where name = ?");
st->Set(1, sc.comment);
st->Set(2, sc.cost);
- st->Set(3, sc.payDay);
+ st->Set(3, static_cast<int16_t>(sc.payDay));
st->Set(4, sc.name);
st->Execute();
tr->Commit();
{
st->Get(3, sc->comment);
st->Get(4, sc->cost);
- st->Get(5, sc->payDay);
+ int16_t pd;
+ st->Get(5, pd);
+ sc->payDay = pd;
}
else
{
SRCS = ./mysql_store.cpp
-STGLIBS = -lstgcommon -lstgcrypto
+STGLIBS = common \
+ crypto
MYSQL_CFLAGS = $(shell mysql_config --cflags)
MYSQL_LDFLAGS = $(shell mysql_config --libs_r)
#include "stg/user_conf.h"
#include "stg/user_stat.h"
#include "stg/blowfish.h"
+#include "stg/plugin_creator.h"
#include "mysql_store.h"
#define adm_enc_passwd "cjeifY8m3"
return 0;
}
-class MYSQL_STORE_CREATOR
-{
-private:
- MYSQL_STORE * ms;
-
-public:
- MYSQL_STORE_CREATOR()
- : ms(new MYSQL_STORE())
- {
- };
- ~MYSQL_STORE_CREATOR()
- {
- delete ms;
- };
-
- MYSQL_STORE * GetStore()
- {
- return ms;
- };
-} msc;
+PLUGIN_CREATOR<MYSQL_STORE> msc;
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
STORE * GetStore()
{
-return msc.GetStore();
+return msc.GetPlugin();
}
//-----------------------------------------------------------------------------
MYSQL_STORE_SETTINGS::MYSQL_STORE_SETTINGS()
- : settings(NULL)
-{
-}
-//-----------------------------------------------------------------------------
-MYSQL_STORE_SETTINGS::~MYSQL_STORE_SETTINGS()
+ : settings(NULL),
+ errorStr(),
+ dbUser(),
+ dbPass(),
+ dbName(),
+ dbHost()
{
-
}
//-----------------------------------------------------------------------------
int MYSQL_STORE_SETTINGS::ParseParam(const vector<PARAM_VALUE> & moduleParams,
return 0;
}
//-----------------------------------------------------------------------------
-const string & MYSQL_STORE_SETTINGS::GetStrError() const
-{
-return errorStr;
-}
-//-----------------------------------------------------------------------------
-string MYSQL_STORE_SETTINGS::GetDBUser() const
-{
-return dbUser;
-}
-//-----------------------------------------------------------------------------
-string MYSQL_STORE_SETTINGS::GetDBPassword() const
-{
-return dbPass;
-}
-//-----------------------------------------------------------------------------
-string MYSQL_STORE_SETTINGS::GetDBHost() const
-{
-return dbHost;
-}
-//-----------------------------------------------------------------------------
-string MYSQL_STORE_SETTINGS::GetDBName() const
-{
-return dbName;
-}
-//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
MYSQL_STORE::MYSQL_STORE()
+ : errorStr(),
+ version("mysql_store v.0.67"),
+ storeSettings(),
+ settings()
{
-version = "mysql_store v.0.67";
-};
-//-----------------------------------------------------------------------------
-MYSQL_STORE::~MYSQL_STORE()
-{
};
//-----------------------------------------------------------------------------
-void MYSQL_STORE::SetSettings(const MODULE_SETTINGS & s)
-{
-settings = s;
-}
-//-----------------------------------------------------------------------------
int MYSQL_STORE::MysqlQuery(const char* sQuery,MYSQL * sock) const
{
int ret,i;
return ret;
}
//-----------------------------------------------------------------------------
-const string & MYSQL_STORE::GetStrError() const
-{
-return errorStr;
-}
-//-----------------------------------------------------------------------------
-const string & MYSQL_STORE::GetVersion() const
-{
-return version;
-}
-//-----------------------------------------------------------------------------
bool MYSQL_STORE::IsTablePresent(const string & str,MYSQL * sock)
{
MYSQL_RES* result;
MYSQL_ROW row;
MYSQL * sock;
-sprintf(qbuf,"SELECT * FROM messages WHERE login='%s' AND id=%lld LIMIT 1",
- login.c_str(), id);
+sprintf(qbuf,"SELECT * FROM messages WHERE login='%s' AND id=%llu LIMIT 1",
+ login.c_str(), static_cast<unsigned long long>(id));
if(MysqlGetQuery(qbuf,sock))
{
{
public:
MYSQL_STORE_SETTINGS();
- virtual ~MYSQL_STORE_SETTINGS();
+ virtual ~MYSQL_STORE_SETTINGS() {}
virtual int ParseSettings(const MODULE_SETTINGS & s);
- virtual const string & GetStrError() const;
+ virtual const string & GetStrError() const { return errorStr; }
- string GetDBUser() const;
- string GetDBPassword() const;
- string GetDBHost() const;
- string GetDBName() const;
+ const string & GetDBUser() const { return dbUser; }
+ const string & GetDBPassword() const { return dbPass; }
+ const string & GetDBHost() const { return dbHost; }
+ const string & GetDBName() const { return dbName; }
private:
+ MYSQL_STORE_SETTINGS(const MYSQL_STORE_SETTINGS & rvalue);
+ MYSQL_STORE_SETTINGS & operator=(const MYSQL_STORE_SETTINGS & rvalue);
+
const MODULE_SETTINGS * settings;
int ParseParam(const vector<PARAM_VALUE> & moduleParams,
{
public:
MYSQL_STORE();
- virtual ~MYSQL_STORE();
- virtual const string & GetStrError() const;
+ virtual ~MYSQL_STORE() {}
+ virtual const string & GetStrError() const { return errorStr; }
//User
virtual int GetUsersList(vector<string> * usersList) const;
virtual int AddService(const string &) const {return 0;};
virtual int DelService(const string &) const {return 0;};
- //virtual BASE_SETTINGS * GetStoreSettings();
- virtual void SetSettings(const MODULE_SETTINGS & s);
+ virtual void SetSettings(const MODULE_SETTINGS & s) { settings = s; }
virtual int ParseSettings();
- virtual const string & GetVersion() const;
+ virtual const string & GetVersion() const { return version; }
private:
+ MYSQL_STORE(const MYSQL_STORE & rvalue);
+ MYSQL_STORE & operator=(const MYSQL_STORE & rvalue);
+
virtual int WriteLogString(const string & str, const string & login) const;
int GetAllParams(vector<string> * ParamList, const string & table, const string & name) const;
int CheckAllTables(MYSQL * sock);
bool IsTablePresent(const string & str,MYSQL * sock);
mutable string errorStr;
-// int Reconnect();
int MysqlQuery(const char* sQuery,MYSQL * sock) const;
int MysqlGetQuery(const char * Query,MYSQL * & sock) const;
int MysqlSetQuery(const char * Query) const;
string version;
MYSQL_STORE_SETTINGS storeSettings;
MODULE_SETTINGS settings;
- //mutable MYSQL mysql;
- //mutable MYSQL* sock;
};
//-----------------------------------------------------------------------------
./postgresql_store_users.cpp \
./postgresql_store_utils.cpp
-STGLIBS = -lstgcommon -lstgcrypto
+STGLIBS = common \
+ crypto \
+ locker
PG_CFLAGS = $(shell pg_config --includedir)
PG_LDFLAGS = $(shell pg_config --libdir)
#include <libpq-fe.h>
-#include "postgresql_store.h"
-#include "postgresql_store_utils.h"
#include "stg/module_settings.h"
+#include "stg/plugin_creator.h"
+#include "postgresql_store_utils.h"
+#include "postgresql_store.h"
-class POSTGRESQL_STORE_CREATOR
-{
-public:
- POSTGRESQL_STORE_CREATOR()
- : pqStore(new POSTGRESQL_STORE())
- {
- };
- ~POSTGRESQL_STORE_CREATOR()
- {
- delete pqStore;
- };
- POSTGRESQL_STORE * GetStore() { return pqStore; };
-private:
- POSTGRESQL_STORE * pqStore;
-} pqStoreeCreator;
+PLUGIN_CREATOR<POSTGRESQL_STORE> pqStoreeCreator;
//-----------------------------------------------------------------------------
STORE * GetStore()
{
-return pqStoreeCreator.GetStore();
+return pqStoreeCreator.GetPlugin();
}
//-----------------------------------------------------------------------------
POSTGRESQL_STORE::POSTGRESQL_STORE()
: versionString("postgresql_store v.1.3"),
+ strError(),
server("localhost"),
database("stargazer"),
user("stg"),
password("123456"),
+ clientEncoding("KOI8"),
+ settings(),
+ mutex(),
version(0),
retries(3),
connection(NULL)
inline const string & GetStrError() const { return strError; };
inline const string & GetVersion() const { return versionString; };
private:
+ POSTGRESQL_STORE(const POSTGRESQL_STORE & rvalue);
+ POSTGRESQL_STORE & operator=(const POSTGRESQL_STORE & rvalue);
+
int StartTransaction() const;
int CommitTransaction() const;
int RollbackTransaction() const;
--- /dev/null
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Author : Maxim Mamontov <faust@stargazer.dp.ua>
+ */
+
+#include <cerrno>
+#include <cassert>
+#include <algorithm>
+
+#include "stg/admin.h"
+#include "stg/common.h"
+#include "services_impl.h"
+
+//-----------------------------------------------------------------------------
+SERVICES_IMPL::SERVICES_IMPL(STORE * st)
+ : SERVICES(),
+ data(),
+ store(st),
+ WriteServLog(GetStgLogger()),
+ searchDescriptors(),
+ handle(0),
+ mutex(),
+ strError()
+{
+pthread_mutex_init(&mutex, NULL);
+Read();
+}
+//-----------------------------------------------------------------------------
+int SERVICES_IMPL::Add(const SERVICE_CONF & service, const ADMIN * admin)
+{
+STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+const PRIV * priv = admin->GetPriv();
+
+if (!priv->serviceChg)
+ {
+ string s = admin->GetLogStr() + " Add service \'" + service.name + "\'. Access denied.";
+ strError = "Access denied.";
+ WriteServLog(s.c_str());
+ return -1;
+ }
+
+srv_iter si(find(data.begin(), data.end(), service));
+
+if (si != data.end())
+ {
+ strError = "Service \'" + service.name + "\' cannot not be added. Service already exist.";
+ WriteServLog("%s %s", admin->GetLogStr().c_str(), strError.c_str());
+
+ return -1;
+ }
+
+data.push_back(service);
+
+if (store->AddService(service.name) == 0)
+ {
+ WriteServLog("%s Service \'%s\' added.",
+ admin->GetLogStr().c_str(), service.name.c_str());
+ return 0;
+ }
+
+strError = "Service \'" + service.name + "\' was not added. Error: " + store->GetStrError();
+WriteServLog("%s %s", admin->GetLogStr().c_str(), strError.c_str());
+
+return -1;
+}
+//-----------------------------------------------------------------------------
+int SERVICES_IMPL::Del(const string & name, const ADMIN * admin)
+{
+STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+const PRIV * priv = admin->GetPriv();
+
+if (!priv->serviceChg)
+ {
+ string s = admin->GetLogStr() + " Delete service \'" + name + "\'. Access denied.";
+ strError = "Access denied.";
+ WriteServLog(s.c_str());
+ return -1;
+ }
+
+srv_iter si(find(data.begin(), data.end(), SERVICE_CONF(name)));
+
+if (si == data.end())
+ {
+ strError = "Service \'" + name + "\' cannot be deleted. Service does not exist.";
+ WriteServLog("%s %s", admin->GetLogStr().c_str(), strError.c_str());
+ return -1;
+ }
+
+map<int, const_srv_iter>::iterator csi;
+csi = searchDescriptors.begin();
+while (csi != searchDescriptors.end())
+ {
+ if (csi->second == si)
+ (csi->second)++;
+ csi++;
+ }
+
+data.remove(*si);
+if (store->DelService(name) < 0)
+ {
+ strError = "Service \'" + name + "\' was not deleted. Error: " + store->GetStrError();
+ WriteServLog("%s %s", admin->GetLogStr().c_str(), strError.c_str());
+
+ return -1;
+ }
+
+WriteServLog("%s Service \'%s\' deleted.", admin->GetLogStr().c_str(), name.c_str());
+return 0;
+}
+//-----------------------------------------------------------------------------
+int SERVICES_IMPL::Change(const SERVICE_CONF & service, const ADMIN * admin)
+{
+STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+const PRIV * priv = admin->GetPriv();
+
+if (!priv->serviceChg)
+ {
+ string s = admin->GetLogStr() + " Change service \'" + service.name + "\'. Access denied.";
+ strError = "Access denied.";
+ WriteServLog(s.c_str());
+ return -1;
+ }
+
+srv_iter si(find(data.begin(), data.end(), service));
+
+if (si == data.end())
+ {
+ strError = "Service \'" + service.name + "\' cannot be changed " + ". Service does not exist.";
+ WriteServLog("%s %s", admin->GetLogStr().c_str(), strError.c_str());
+ return -1;
+ }
+
+*si = service;
+if (store->SaveService(service))
+ {
+ WriteServLog("Cannot write service %s.", service.name.c_str());
+ WriteServLog("%s", store->GetStrError().c_str());
+ return -1;
+ }
+
+WriteServLog("%s Service \'%s\' changed.",
+ admin->GetLogStr().c_str(), service.name.c_str());
+
+return 0;
+}
+//-----------------------------------------------------------------------------
+bool SERVICES_IMPL::Read()
+{
+STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+vector<string> servicesList;
+if (store->GetServicesList(&servicesList) < 0)
+ {
+ WriteServLog(store->GetStrError().c_str());
+ return true;
+ }
+
+for (size_t i = 0; i < servicesList.size(); i++)
+ {
+ SERVICE_CONF service;
+
+ if (store->RestoreService(&service, servicesList[i]))
+ {
+ WriteServLog(store->GetStrError().c_str());
+ return true;
+ }
+
+ data.push_back(service);
+ }
+return false;
+}
+//-----------------------------------------------------------------------------
+bool SERVICES_IMPL::Find(const string & name, SERVICE_CONF * service)
+{
+assert(service != NULL && "Pointer to service is not null");
+
+STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+if (data.empty())
+ return false;
+
+srv_iter si(find(data.begin(), data.end(), SERVICE_CONF(name)));
+
+if (si != data.end())
+ {
+ *service = *si;
+ return false;
+ }
+
+return true;
+}
+//-----------------------------------------------------------------------------
+bool SERVICES_IMPL::Exists(const string & name) const
+{
+STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+if (data.empty())
+ {
+ printfd(__FILE__, "no admin in system!\n");
+ return true;
+ }
+
+const_srv_iter si(find(data.begin(), data.end(), SERVICE_CONF(name)));
+
+if (si != data.end())
+ return true;
+
+return false;
+}
+//-----------------------------------------------------------------------------
+int SERVICES_IMPL::OpenSearch() const
+{
+STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+handle++;
+searchDescriptors[handle] = data.begin();
+return handle;
+}
+//-----------------------------------------------------------------------------
+int SERVICES_IMPL::SearchNext(int h, SERVICE_CONF * service) const
+{
+STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+if (searchDescriptors.find(h) == searchDescriptors.end())
+ {
+ WriteServLog("SERVICES. Incorrect search handle.");
+ return -1;
+ }
+
+if (searchDescriptors[h] == data.end())
+ return -1;
+
+*service = *searchDescriptors[h]++;
+
+return 0;
+}
+//-----------------------------------------------------------------------------
+int SERVICES_IMPL::CloseSearch(int h) const
+{
+STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+if (searchDescriptors.find(h) != searchDescriptors.end())
+ {
+ searchDescriptors.erase(searchDescriptors.find(h));
+ return 0;
+ }
+
+WriteServLog("SERVICES. Incorrect search handle.");
+return -1;
+}
+//-----------------------------------------------------------------------------
--- /dev/null
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Author : Maxim Mamontov <faust@stargazer.dp.ua>
+ */
+
+#ifndef SERVICES_IMPL_H
+#define SERVICES_IMPL_H
+
+#include <pthread.h>
+
+#include <list>
+#include <map>
+#include <string>
+
+#include "stg/services.h"
+#include "stg/service_conf.h"
+#include "stg/locker.h"
+#include "stg/store.h"
+#include "stg/noncopyable.h"
+#include "stg/logger.h"
+
+class ADMIN;
+
+class SERVICES_IMPL : private NONCOPYABLE, public SERVICES {
+public:
+ SERVICES_IMPL(STORE * st);
+ virtual ~SERVICES_IMPL() {}
+
+ int Add(const SERVICE_CONF & service, const ADMIN * admin);
+ int Del(const std::string & name, const ADMIN * admin);
+ int Change(const SERVICE_CONF & service, const ADMIN * admin);
+ bool Find(const std::string & name, SERVICE_CONF * service);
+ bool Exists(const std::string & name) const;
+ const std::string & GetStrError() const { return strError; }
+
+ size_t Count() const { return data.size(); }
+
+ int OpenSearch() const;
+ int SearchNext(int, SERVICE_CONF * service) const;
+ int CloseSearch(int) const;
+
+private:
+ SERVICES_IMPL(const SERVICES_IMPL & rvalue);
+ SERVICES_IMPL & operator=(const SERVICES_IMPL & rvalue);
+
+ typedef list<SERVICE_CONF>::iterator srv_iter;
+ typedef list<SERVICE_CONF>::const_iterator const_srv_iter;
+
+ bool Read();
+
+ std::list<SERVICE_CONF> data;
+ STORE * store;
+ STG_LOGGER & WriteServLog;
+ mutable std::map<int, const_srv_iter> searchDescriptors;
+ mutable unsigned int handle;
+ mutable pthread_mutex_t mutex;
+ std::string strError;
+};
+
+#endif
{
}
//-----------------------------------------------------------------------------
-int SETTINGS_IMPL::ParseYesNo(const string & value, bool * val)
-{
-if (0 == strcasecmp(value.c_str(), "yes"))
- {
- *val = true;
- return 0;
- }
-if (0 == strcasecmp(value.c_str(), "no"))
- {
- *val = false;
- return 0;
- }
-
-strError = "Incorrect value \'" + value + "\'.";
-return -1;
-}
-//-----------------------------------------------------------------------------
-int SETTINGS_IMPL::ParseInt(const string & value, int * val)
-{
-if (str2x<int>(value, *val))
- {
- strError = "Cannot convert \'" + value + "\' to integer.";
- return -1;
- }
-return 0;
-}
-//-----------------------------------------------------------------------------
-int SETTINGS_IMPL::ParseUnsigned(const string & value, unsigned * val)
-{
-if (str2x<unsigned>(value, *val))
- {
- strError = "Cannot convert \'" + value + "\' to unsigned integer.";
- return -1;
- }
-return 0;
-}
-//-----------------------------------------------------------------------------
-int SETTINGS_IMPL::ParseIntInRange(const string & value, int min, int max, int * val)
-{
-if (ParseInt(value, val) != 0)
- return -1;
-
-if (*val < min || *val > max)
- {
- strError = "Value \'" + value + "\' out of range.";
- return -1;
- }
-
-return 0;
-}
-//-----------------------------------------------------------------------------
-int SETTINGS_IMPL::ParseUnsignedInRange(const string & value, unsigned min, unsigned max, unsigned * val)
-{
-if (ParseUnsigned(value, val) != 0)
- return -1;
-
-if (*val < min || *val > max)
- {
- strError = "Value \'" + value + "\' out of range.";
- return -1;
- }
-
-return 0;
-}
-//-----------------------------------------------------------------------------
int SETTINGS_IMPL::ParseModuleSettings(const DOTCONFDocumentNode * node, vector<PARAM_VALUE> * params)
{
const DOTCONFDocumentNode * childNode;
dsPeriod_1,
dsPeriod_1_2,
dsPeriod_1_4,
-dsPeriod_1_6,
+dsPeriod_1_6
};
//-----------------------------------------------------------------------------
class STG_LOGGER;
private:
- int ParseInt(const std::string & value, int * val);
- int ParseUnsigned(const std::string & value, unsigned * val);
- int ParseIntInRange(const std::string & value, int min, int max, int * val);
- int ParseUnsignedInRange(const std::string & value, unsigned min, unsigned max, unsigned * val);
- int ParseYesNo(const std::string & value, bool * val);
- int ParseDetailStatWritePeriod(const std::string & detailStatPeriodStr);
-
+ int ParseDetailStatWritePeriod(const std::string & str);
int ParseModuleSettings(const DOTCONFDocumentNode * dirNameNode, std::vector<PARAM_VALUE> * params);
static void ErrorCallback(void * data, const char * buf);
#include <ctime>
#include <cstring>
+#include <csignal>
#include "stg/common.h"
stgTime = time(NULL);
#endif
+sigset_t signalSet;
+sigfillset(&signalSet);
+pthread_sigmask(SIG_BLOCK, &signalSet, NULL);
+
nonstop = 1;
isTimerRunning = true;
while (nonstop)
#ifdef STG_TIMER_DEBUG
struct timespec ts = {0, 1000000000 / TIME_SPEED};
nanosleep(&ts, NULL);
- //usleep(1000000 / TIME_SPEED);
stgTime++;
#else
struct timespec ts = {0, 500000000};
nanosleep(&ts, NULL);
- //usleep(500000);
stgTime = time(NULL);
#endif
}
#ifdef STG_TIMER_DEBUG
struct timespec ts = {(t / TIME_SPEED) / 1000000, ((t / TIME_SPEED) % 1000000) * 1000};
return nanosleep(&ts, NULL);
-//return usleep(t / TIME_SPEED);
#else
struct timespec ts = {t / 1000000, (t % 1000000) * 1000};
return nanosleep(&ts, NULL);
-//return usleep(t);
#endif
}
//-----------------------------------------------------------------------------
STORE * GetStore() { return plugin; }
const std::string & GetStrError() const { return errorStr; }
+
private:
+ STORE_LOADER(const STORE_LOADER & rvalue);
+ STORE_LOADER & operator=(const STORE_LOADER & rvalue);
+
bool isLoaded;
void * handle;
STORE * plugin;
#include "stg_timer.h"
//-----------------------------------------------------------------------------
-TARIFF & TARIFF_IMPL::operator=(const TARIFF_DATA & td)
+TARIFF_IMPL & TARIFF_IMPL::operator=(const TARIFF_DATA & td)
{
tariffData = td;
return *this;
}
//-----------------------------------------------------------------------------
-TARIFF & TARIFF_IMPL::operator=(const TARIFF & t)
+TARIFF_IMPL & TARIFF_IMPL::operator=(const TARIFF_IMPL & t)
{
-tariffData = t.GetTariffData();
+tariffData = t.tariffData;
return *this;
}
//-----------------------------------------------------------------------------
int GetThreshold(int dir) const;
const TARIFF_DATA & GetTariffData() const { return tariffData; }
- TARIFF & operator=(const TARIFF_DATA & td);
- TARIFF & operator=(const TARIFF & t);
- bool operator==(const TARIFF & rhs) const { return GetName() == rhs.GetName(); }
- bool operator!=(const TARIFF & rhs) const { return GetName() != rhs.GetName(); }
+ TARIFF_IMPL & operator=(const TARIFF_DATA & td);
+ TARIFF_IMPL & operator=(const TARIFF_IMPL & t);
+ bool operator==(const TARIFF_IMPL & rhs) const { return GetName() == rhs.GetName(); }
+ bool operator!=(const TARIFF_IMPL & rhs) const { return GetName() != rhs.GetName(); }
private:
TARIFF_DATA tariffData;
tariffs(),
store(st),
WriteServLog(GetStgLogger()),
+ mutex(),
strError(),
- noTariff(NO_TARIFF_NAME)
+ noTariff(NO_TARIFF_NAME),
+ onAddNotifiers(),
+ onDelNotifiers()
{
pthread_mutex_init(&mutex, NULL);
ReadTariffs();
return 0;
}
//-----------------------------------------------------------------------------
-int TARIFFS_IMPL::GetTariffsNum() const
+size_t TARIFFS_IMPL::Count() const
{
STG_LOCKER lock(&mutex, __FILE__, __LINE__);
return tariffs.size();
return -1;
}
-STG_LOCKER lock(&mutex, __FILE__, __LINE__);
-
-list<TARIFF_IMPL>::iterator ti;
-ti = find(tariffs.begin(), tariffs.end(), TARIFF_IMPL(name));
+TARIFF_DATA td;
-if (ti == tariffs.end())
{
- strError = "Tariff \'" + name + "\' cannot be deleted. Tariff does not exist.";
- WriteServLog("%s %s", admin->GetLogStr().c_str(), strError.c_str());
- return -1;
+ STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+
+ list<TARIFF_IMPL>::iterator ti;
+ ti = find(tariffs.begin(), tariffs.end(), TARIFF_IMPL(name));
+
+ if (ti == tariffs.end())
+ {
+ strError = "Tariff \'" + name + "\' cannot be deleted. Tariff does not exist.";
+ WriteServLog("%s %s", admin->GetLogStr().c_str(), strError.c_str());
+ return -1;
+ }
+
+ if (store->DelTariff(name))
+ {
+ WriteServLog("Cannot delete tariff %s.", name.c_str());
+ WriteServLog("%s", store->GetStrError().c_str());
+ return -1;
+ }
+
+ td = ti->GetTariffData();
+
+ tariffs.erase(ti);
}
-if (store->DelTariff(name))
+std::set<NOTIFIER_BASE<TARIFF_DATA> *>::iterator ni = onDelNotifiers.begin();
+while (ni != onDelNotifiers.end())
{
- WriteServLog("Cannot delete tariff %s.", name.c_str());
- WriteServLog("%s", store->GetStrError().c_str());
- return -1;
+ (*ni)->Notify(td);
+ ++ni;
}
-tariffs.erase(ti);
-
WriteServLog("%s Tariff \'%s\' deleted.",
admin->GetLogStr().c_str(),
name.c_str());
return -1;
}
-STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+ {
+ STG_LOCKER lock(&mutex, __FILE__, __LINE__);
-list<TARIFF_IMPL>::iterator ti;
-ti = find(tariffs.begin(), tariffs.end(), TARIFF_IMPL(name));
+ list<TARIFF_IMPL>::iterator ti;
+ ti = find(tariffs.begin(), tariffs.end(), TARIFF_IMPL(name));
-if (ti != tariffs.end())
- {
- strError = "Tariff \'" + name + "\' cannot be added. Tariff already exist.";
- WriteServLog("%s %s", admin->GetLogStr().c_str(), strError.c_str());
- return -1;
- }
+ if (ti != tariffs.end())
+ {
+ strError = "Tariff \'" + name + "\' cannot be added. Tariff already exist.";
+ WriteServLog("%s %s", admin->GetLogStr().c_str(), strError.c_str());
+ return -1;
+ }
-tariffs.push_back(TARIFF_IMPL(name));
+ tariffs.push_back(TARIFF_IMPL(name));
+ }
if (store->AddTariff(name) < 0)
{
return -1;
}
+// Fire all "on add" notifiers
+std::set<NOTIFIER_BASE<TARIFF_DATA> *>::iterator ni = onAddNotifiers.begin();
+while (ni != onAddNotifiers.end())
+ {
+ (*ni)->Notify(tariffs.back().GetTariffData());
+ ++ni;
+ }
+
WriteServLog("%s Tariff \'%s\' added.",
admin->GetLogStr().c_str(), name.c_str());
}
}
//-----------------------------------------------------------------------------
+void TARIFFS_IMPL::AddNotifierAdd(NOTIFIER_BASE<TARIFF_DATA> * n)
+{
+STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+onAddNotifiers.insert(n);
+}
+//-----------------------------------------------------------------------------
+void TARIFFS_IMPL::DelNotifierAdd(NOTIFIER_BASE<TARIFF_DATA> * n)
+{
+STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+onAddNotifiers.erase(n);
+}
+//-----------------------------------------------------------------------------
+void TARIFFS_IMPL::AddNotifierDel(NOTIFIER_BASE<TARIFF_DATA> * n)
+{
+STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+onDelNotifiers.insert(n);
+}
+//-----------------------------------------------------------------------------
+void TARIFFS_IMPL::DelNotifierDel(NOTIFIER_BASE<TARIFF_DATA> * n)
+{
+STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+onDelNotifiers.erase(n);
+}
+//-----------------------------------------------------------------------------
- /*
- $Revision: 1.7 $
- $Date: 2010/10/07 18:43:21 $
- */
-
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* Author : Boris Mikhailenko <stg34@stargazer.dp.ua>
*/
-/*
- $Revision: 1.7 $
- $Date: 2010/10/07 18:43:21 $
- $Author: faust $
- */
-
#ifndef TARIFFS_IMPL_H
#define TARIFFS_IMPL_H
#include <string>
#include <list>
+#include <set>
#include "stg/tariff.h"
#include "stg/tariffs.h"
int ReadTariffs ();
const TARIFF * FindByName(const std::string & name) const;
const TARIFF * GetNoTariff() const { return &noTariff; };
- int GetTariffsNum() const;
+ size_t Count() const;
int Del(const std::string & name, const ADMIN * admin);
int Add(const std::string & name, const ADMIN * admin);
int Chg(const TARIFF_DATA & td, const ADMIN * admin);
+ void AddNotifierAdd(NOTIFIER_BASE<TARIFF_DATA> * notifier);
+ void DelNotifierAdd(NOTIFIER_BASE<TARIFF_DATA> * notifier);
+
+ void AddNotifierDel(NOTIFIER_BASE<TARIFF_DATA> * notifier);
+ void DelNotifierDel(NOTIFIER_BASE<TARIFF_DATA> * notifier);
+
void GetTariffsData(std::list<TARIFF_DATA> * tdl);
const std::string & GetStrError() const { return strError; }
+
private:
+ TARIFFS_IMPL(const TARIFFS_IMPL & rvalue);
+ TARIFFS_IMPL & operator=(const TARIFFS_IMPL & rvalue);
+
std::list<TARIFF_IMPL> tariffs;
STORE * store;
STG_LOGGER & WriteServLog;
mutable pthread_mutex_t mutex;
std::string strError;
TARIFF_IMPL noTariff;
+
+ std::set<NOTIFIER_BASE<TARIFF_DATA>*> onAddNotifiers;
+ std::set<NOTIFIER_BASE<TARIFF_DATA>*> onDelNotifiers;
};
#endif
//-----------------------------------------------------------------------------
TRAFFCOUNTER_IMPL::TRAFFCOUNTER_IMPL(USERS_IMPL * u, const std::string & fn)
: TRAFFCOUNTER(),
+ rules(),
+ packets(),
+ ip2packets(),
+ dirName(),
WriteServLog(GetStgLogger()),
rulesFileName(fn),
+ monitorDir(),
monitoring(false),
users(u),
running(false),
stopped(true),
+ mutex(),
+ thread(),
+ ipBeforeNotifiers(),
+ ipAfterNotifiers(),
addUserNotifier(*this),
delUserNotifier(*this)
{
printfd(__FILE__, "TRAFFCOUNTER::Start()\n");
int h = users->OpenSearch();
+assert(h && "USERS::OpenSearch is always correct");
USER_IMPL * u;
-if (!h)
- {
- printfd(__FILE__, "TRAFFCOUNTER_IMPL::Start() - Cannot get users\n");
- WriteServLog("TRAFFCOUNTER: Cannot get users.");
- return -1;
- }
while (users->SearchNext(h, &u) == 0)
{
running = false;
int h = users->OpenSearch();
-if (!h)
- {
- WriteServLog("TRAFFCOUNTER: Fatal error: Cannot get users.");
- return -1;
- }
+assert(h && "USERS::OpenSearch is always correct");
USER_IMPL * u;
while (users->SearchNext(h, &u) == 0)
nanosleep(&ts, NULL);
}
-//after 5 seconds waiting thread still running. now kill it
if (!stopped)
- {
- printfd(__FILE__, "kill TRAFFCOUNTER thread.\n");
- if (pthread_kill(thread, SIGINT))
- {
- return -1;
- }
- printfd(__FILE__, "TRAFFCOUNTER killed\n");
- }
+ return -1;
+
printfd(__FILE__, "TRAFFCOUNTER::Stop()\n");
return 0;
//-----------------------------------------------------------------------------
void * TRAFFCOUNTER_IMPL::Run(void * data)
{
+sigset_t signalSet;
+sigfillset(&signalSet);
+pthread_sigmask(SIG_BLOCK, &signalSet, NULL);
+
TRAFFCOUNTER_IMPL * tc = static_cast<TRAFFCOUNTER_IMPL *>(data);
tc->stopped = false;
int c = 0;
if (!foundD)
*dirD = DIR_NUM;
-
-return;
-};
+}
//-----------------------------------------------------------------------------
void TRAFFCOUNTER_IMPL::SetRulesFile(const std::string & fn)
{
rul.proto = 0xff;
rul.dir = 0xff;
- for (int i = 0; i < PROTOMAX; i++)
+ for (size_t i = 0; i < PROTOMAX; i++)
{
if (strcasecmp(tp, protoName[i]) == 0)
rul.proto = i;
}
- for (int i = 0; i < DIR_NUM + 1; i++)
+ for (size_t i = 0; i < DIR_NUM + 1; i++)
{
if (td == dirName[i])
rul.dir = i;
}
// Convert strings to mask, ports and IP
-int prt1, prt2, msk;
-unsigned ip;
+uint16_t prt1, prt2, msk;
+struct in_addr ipaddr;
char *res;
msk = strtol(mask, &res, 10);
if (*res != 0)
return true;
-int r = inet_aton(addr, (struct in_addr*)&ip);
+int r = inet_aton(addr, &ipaddr);
if (r == 0)
return true;
-rule->ip = ip;
+rule->ip = ipaddr.s_addr;
rule->mask = CalcMask(msk);
//msk = 1;
//printfd(__FILE__, "msk=%d mask=%08X mask=%08X\n", msk, rule->mask, (0xFFffFFff << (32 - msk)));
-if ((ip & rule->mask) != ip)
+if ((ipaddr.s_addr & rule->mask) != ipaddr.s_addr)
{
printfd(__FILE__, "TRAFFCOUNTER_IMPL::ParseAddress() - Address does'n match mask.\n");
WriteServLog("Address does'n match mask.");
printf("ALL ");
break;
}
-printf("dir=%d \n", rule.dir);
-return;
+printf("dir=%u \n", static_cast<unsigned>(rule.dir));
}
//-----------------------------------------------------------------------------
void TRAFFCOUNTER_IMPL::SetMonitorDir(const std::string & monitorDir)
//-----------------------------------------------------------------------------
class TRF_IP_BEFORE: public PROPERTY_NOTIFIER_BASE<uint32_t> {
public:
- TRF_IP_BEFORE(TRAFFCOUNTER_IMPL & t, USER_IMPL * u)
- : PROPERTY_NOTIFIER_BASE<uint32_t>(),
- traffCnt(t),
- user(u)
- {}
- void Notify(const uint32_t & oldValue, const uint32_t & newValue);
- void SetUser(USER_IMPL * u) { user = u; }
- USER_IMPL * GetUser() const { return user; }
+ TRF_IP_BEFORE(TRAFFCOUNTER_IMPL & t, USER_IMPL * u)
+ : PROPERTY_NOTIFIER_BASE<uint32_t>(),
+ traffCnt(t),
+ user(u)
+ {}
+ TRF_IP_BEFORE(const TRF_IP_BEFORE & rvalue)
+ : PROPERTY_NOTIFIER_BASE<uint32_t>(),
+ traffCnt(rvalue.traffCnt),
+ user(rvalue.user)
+ {}
+ void Notify(const uint32_t & oldValue, const uint32_t & newValue);
+ void SetUser(USER_IMPL * u) { user = u; }
+ USER_IMPL * GetUser() const { return user; }
private:
+ TRF_IP_BEFORE & operator=(const TRF_IP_BEFORE & rvalue);
+
TRAFFCOUNTER_IMPL & traffCnt;
- USER_IMPL * user;
+ USER_IMPL * user;
};
//-----------------------------------------------------------------------------
class TRF_IP_AFTER: public PROPERTY_NOTIFIER_BASE<uint32_t> {
public:
- TRF_IP_AFTER(TRAFFCOUNTER_IMPL & t, USER_IMPL * u)
- : PROPERTY_NOTIFIER_BASE<uint32_t>(),
- traffCnt(t),
- user(u)
- {}
- void Notify(const uint32_t & oldValue, const uint32_t & newValue);
- void SetUser(USER_IMPL * u) { user = u; }
- USER_IMPL * GetUser() const { return user; }
+ TRF_IP_AFTER(TRAFFCOUNTER_IMPL & t, USER_IMPL * u)
+ : PROPERTY_NOTIFIER_BASE<uint32_t>(),
+ traffCnt(t),
+ user(u)
+ {}
+ TRF_IP_AFTER(const TRF_IP_AFTER & rvalue)
+ : PROPERTY_NOTIFIER_BASE<uint32_t>(),
+ traffCnt(rvalue.traffCnt),
+ user(rvalue.user)
+ {}
+ void Notify(const uint32_t & oldValue, const uint32_t & newValue);
+ void SetUser(USER_IMPL * u) { user = u; }
+ USER_IMPL * GetUser() const { return user; }
private:
+ TRF_IP_AFTER & operator=(const TRF_IP_AFTER & rvalue);
+
TRAFFCOUNTER_IMPL & traffCnt;
- USER_IMPL * user;
+ USER_IMPL * user;
};
//-----------------------------------------------------------------------------
class ADD_USER_NONIFIER: public NOTIFIER_BASE<USER_IMPL_PTR> {
{}
virtual ~ADD_USER_NONIFIER() {}
void Notify(const USER_IMPL_PTR & user);
+
private:
+ ADD_USER_NONIFIER(const ADD_USER_NONIFIER & rvalue);
+ ADD_USER_NONIFIER & operator=(const ADD_USER_NONIFIER & rvalue);
+
TRAFFCOUNTER_IMPL & traffCnt;
};
//-----------------------------------------------------------------------------
{}
virtual ~DEL_USER_NONIFIER() {}
void Notify(const USER_IMPL_PTR & user);
+
private:
+ DEL_USER_NONIFIER(const DEL_USER_NONIFIER & rvalue);
+ DEL_USER_NONIFIER & operator=(const DEL_USER_NONIFIER & rvalue);
+
TRAFFCOUNTER_IMPL & traffCnt;
};
//-----------------------------------------------------------------------------
void Process(const RAW_PACKET & rawPacket);
void SetMonitorDir(const std::string & monitorDir);
+ size_t RulesCount() const { return rules.size(); }
+
private:
+ TRAFFCOUNTER_IMPL(const TRAFFCOUNTER_IMPL & rvalue);
+ TRAFFCOUNTER_IMPL & operator=(const TRAFFCOUNTER_IMPL & rvalue);
+
bool ParseAddress(const char * ta, RULE * rule) const;
uint32_t CalcMask(uint32_t msk) const;
void FreeRules();
users(u),
property(s->GetScriptsDir()),
WriteServLog(GetStgLogger()),
+ lastScanMessages(0),
login(),
id(0),
__connected(0),
connected(__connected),
+ enabledDirs(),
userIDGenerator(),
__currIP(0),
currIP(__currIP),
store(st),
tariffs(t),
tariff(NULL),
+ traffStat(),
+ traffStatSaved(),
+ settings(s),
+ authorizedBy(),
+ messages(),
+ deleted(false),
+ lastWriteStat(0),
+ lastWriteDetailedStat(0),
cash(property.cash),
up(property.up),
down(property.down),
userdata7(property.userdata7),
userdata8(property.userdata8),
userdata9(property.userdata9),
+ sessionUpload(),
+ sessionDownload(),
passiveNotifier(this),
tariffNotifier(this),
cashNotifier(this),
- ipNotifier(this)
+ ipNotifier(this),
+ mutex(),
+ errorStr()
{
-settings = s;
-
password = "*_EMPTY_PASSWORD_*";
tariffName = NO_TARIFF_NAME;
-connected = 0;
ips = StrToIPS("*");
-deleted = false;
lastWriteStat = stgTime + random() % settings->GetStatWritePeriod();
lastWriteDetailedStat = stgTime;
property.cash.AddBeforeNotifier(&cashNotifier);
ips.AddAfterNotifier(&ipNotifier);
-lastScanMessages = 0;
-
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
}
#else
USER_IMPL::USER_IMPL(const SETTINGS_IMPL * s,
- const STORE * st,
- const TARIFFS * t,
- const ADMIN * a,
- const USERS * u)
+ const STORE * st,
+ const TARIFFS * t,
+ const ADMIN * a,
+ const USERS * u)
: USER(),
users(u),
property(s->GetScriptsDir()),
WriteServLog(GetStgLogger()),
+ lastScanMessages(0),
login(),
id(0),
__connected(0),
connected(__connected),
+ enabledDirs(),
userIDGenerator(),
__currIP(0),
currIP(__currIP),
store(st),
tariffs(t),
tariff(NULL),
+ traffStat(),
+ traffStatSaved(),
+ settings(s),
+ authorizedBy(),
+ messages(),
+ deleted(false),
+ lastWriteStat(0),
+ lastWriteDetailedStat(0),
cash(property.cash),
up(property.up),
down(property.down),
userdata7(property.userdata7),
userdata8(property.userdata8),
userdata9(property.userdata9),
+ sessionUpload(),
+ sessionDownload(),
passiveNotifier(this),
tariffNotifier(this),
cashNotifier(this),
- ipNotifier(this)
+ ipNotifier(this),
+ mutex(),
+ errorStr()
{
-settings = s;
-
password = "*_EMPTY_PASSWORD_*";
tariffName = NO_TARIFF_NAME;
-connected = 0;
ips = StrToIPS("*");
-deleted = false;
lastWriteStat = stgTime + random() % settings->GetStatWritePeriod();
lastWriteDetailedStat = stgTime;
property.cash.AddBeforeNotifier(&cashNotifier);
ips.AddAfterNotifier(&ipNotifier);
-lastScanMessages = 0;
-
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
users(u.users),
property(u.settings->GetScriptsDir()),
WriteServLog(GetStgLogger()),
+ lastScanMessages(0),
login(u.login),
id(u.id),
- __connected(u.__connected),
+ __connected(0),
connected(__connected),
+ enabledDirs(),
+ userIDGenerator(u.userIDGenerator),
__currIP(u.__currIP),
currIP(__currIP),
lastIPForDisconnect(0),
store(u.store),
tariffs(u.tariffs),
tariff(u.tariff),
+ traffStat(u.traffStat),
+ traffStatSaved(u.traffStatSaved),
+ settings(u.settings),
+ authorizedBy(),
+ messages(u.messages),
+ deleted(u.deleted),
+ lastWriteStat(u.lastWriteStat),
+ lastWriteDetailedStat(u.lastWriteDetailedStat),
cash(property.cash),
up(property.up),
down(property.down),
userdata7(property.userdata7),
userdata8(property.userdata8),
userdata9(property.userdata9),
+ sessionUpload(),
+ sessionDownload(),
passiveNotifier(this),
tariffNotifier(this),
cashNotifier(this),
- ipNotifier(this)
+ ipNotifier(this),
+ mutex(),
+ errorStr()
{
if (&u == this)
return;
-connected = 0;
-
-deleted = u.deleted;
-
-lastWriteStat = u.lastWriteStat;
-lastWriteDetailedStat = u.lastWriteDetailedStat;
-
-settings = u.settings;
-
property.tariffName.AddBeforeNotifier(&tariffNotifier);
property.passive.AddBeforeNotifier(&passiveNotifier);
property.cash.AddBeforeNotifier(&cashNotifier);
ips.AddAfterNotifier(&ipNotifier);
-lastScanMessages = 0;
-
property.SetProperties(u.property);
pthread_mutexattr_t attr;
if (store->GetMessageHdrs(&hdrsList, login))
{
printfd(__FILE__, "Error GetMessageHdrs %s\n", store->GetStrError().c_str());
+ WriteServLog("Cannot read user %s. Error reading message headers: %s.",
+ login.c_str(),
+ store->GetStrError().c_str());
return -1;
}
enabledDirs[i] = dirs & (1 << i);
}
-if (authorizedBy.size())
+if (!authorizedBy.empty())
{
if (currIP != ip)
{
id,
dirsStr);
- ScriptExec(scriptOnConnectParams);
+ ScriptExec(scriptOnConnectParams.c_str());
}
else
{
id,
dirsStr);
- ScriptExec(scriptOnDisonnectParams);
+ ScriptExec(scriptOnDisonnectParams.c_str());
}
else
{
scriptOnAdd.c_str(),
login.c_str());
- ScriptExec(scriptOnAddParams);
+ ScriptExec(scriptOnAddParams.c_str());
}
else
{
scriptOnDel.c_str(),
login.c_str());
- ScriptExec(scriptOnDelParams);
+ ScriptExec(scriptOnDelParams.c_str());
}
else
{
property.cash.Set(c - fee, sysAdmin, login, store, "Subscriber fee charge");
break;
case 1:
- if (c > 0)
+ if (c + credit >= 0)
property.cash.Set(c - fee, sysAdmin, login, store, "Subscriber fee charge");
break;
case 2:
- if (c > fee)
+ if (c + credit >= fee)
property.cash.Set(c - fee, sysAdmin, login, store, "Subscriber fee charge");
break;
}
}
double c = cash;
-printfd(__FILE__, "login: %8s Fee=%f PassiveTimePart=%f fee=%f\n",
+printfd(__FILE__, "login: %8s Cash=%f Credit=%f Fee=%f PassiveTimePart=%f fee=%f\n",
login.c_str(),
+ cash.ConstData(),
+ credit.ConstData(),
tariff->GetFee(),
passiveTimePart,
fee);
SetPrepaidTraff();
break;
case 1:
- if (c > 0)
+ if (c + credit >= 0)
{
property.cash.Set(c - fee, sysAdmin, login, store, "Subscriber fee charge");
SetPrepaidTraff();
}
break;
case 2:
- if (c > fee)
+ if (c + credit >= fee)
{
property.cash.Set(c - fee, sysAdmin, login, store, "Subscriber fee charge");
SetPrepaidTraff();
void Notify(const int & oldPassive, const int & newPassive);
private:
+ CHG_PASSIVE_NOTIFIER(const CHG_PASSIVE_NOTIFIER & rvalue);
+ CHG_PASSIVE_NOTIFIER & operator=(const CHG_PASSIVE_NOTIFIER & rvalue);
+
USER_IMPL * user;
};
//-----------------------------------------------------------------------------
void Notify(const std::string & oldTariff, const std::string & newTariff);
private:
+ CHG_TARIFF_NOTIFIER(const CHG_TARIFF_NOTIFIER & rvalue);
+ CHG_TARIFF_NOTIFIER & operator=(const CHG_TARIFF_NOTIFIER & rvalue);
+
USER_IMPL * user;
};
//-----------------------------------------------------------------------------
void Notify(const double & oldCash, const double & newCash);
private:
+ CHG_CASH_NOTIFIER(const CHG_CASH_NOTIFIER & rvalue);
+ CHG_CASH_NOTIFIER & operator=(const CHG_CASH_NOTIFIER & rvalue);
+
USER_IMPL * user;
};
//-----------------------------------------------------------------------------
class CHG_IPS_NOTIFIER : public PROPERTY_NOTIFIER_BASE<USER_IPS>,
private NONCOPYABLE {
public:
+ CHG_IPS_NOTIFIER(const CHG_IPS_NOTIFIER & rvalue);
+ CHG_IPS_NOTIFIER & operator=(const CHG_IPS_NOTIFIER & rvalue);
+
CHG_IPS_NOTIFIER(USER_IMPL * u) : user(u) {}
void Notify(const USER_IPS & oldIPs, const USER_IPS & newIPs);
void OnDelete();
private:
+ USER_IMPL & operator=(const USER_IMPL & rvalue);
+
const USERS * users;
USER_PROPERTIES property;
STG_LOGGER & WriteServLog;
CHG_PASSIVE_NOTIFIER passiveNotifier;
CHG_TARIFF_NOTIFIER tariffNotifier;
CHG_CASH_NOTIFIER cashNotifier;
- CHG_IPS_NOTIFIER ipNotifier;
+ CHG_IPS_NOTIFIER ipNotifier;
mutable pthread_mutex_t mutex;
#include "stg/user_property.h"
-//-----------------------------------------------------------------------------
USER_PROPERTIES::USER_PROPERTIES(const std::string & sd)
-:
-cash (stat.cash, "cash", false, true, GetStgLogger(), sd),
-up (stat.up, "upload", false, true, GetStgLogger(), sd),
-down (stat.down, "download", false, true, GetStgLogger(), sd),
-lastCashAdd (stat.lastCashAdd, "lastCashAdd", false, true, GetStgLogger(), sd),
-passiveTime (stat.passiveTime, "passiveTime", false, true, GetStgLogger(), sd),
-lastCashAddTime (stat.lastCashAddTime, "lastCashAddTime", false, true, GetStgLogger(), sd),
-freeMb (stat.freeMb, "freeMb", false, true, GetStgLogger(), sd),
-lastActivityTime(stat.lastActivityTime, "lastActivityTime", false, true, GetStgLogger(), sd),
+ : stat(),
+ conf(),
+ cash (stat.cash, "cash", false, true, GetStgLogger(), sd),
+ up (stat.up, "upload", false, true, GetStgLogger(), sd),
+ down (stat.down, "download", false, true, GetStgLogger(), sd),
+ lastCashAdd (stat.lastCashAdd, "lastCashAdd", false, true, GetStgLogger(), sd),
+ passiveTime (stat.passiveTime, "passiveTime", false, true, GetStgLogger(), sd),
+ lastCashAddTime (stat.lastCashAddTime, "lastCashAddTime", false, true, GetStgLogger(), sd),
+ freeMb (stat.freeMb, "freeMb", false, true, GetStgLogger(), sd),
+ lastActivityTime(stat.lastActivityTime, "lastActivityTime", false, true, GetStgLogger(), sd),
-password (conf.password, "password", true, false, GetStgLogger(), sd),
-passive (conf.passive, "passive", false, false, GetStgLogger(), sd),
-disabled (conf.disabled, "disabled", false, false, GetStgLogger(), sd),
-disabledDetailStat(conf.disabledDetailStat, "DisabledDetailStat", false, false, GetStgLogger(), sd),
-alwaysOnline(conf.alwaysOnline, "alwaysOnline", false, false, GetStgLogger(), sd),
-tariffName (conf.tariffName, "tariff", false, false, GetStgLogger(), sd),
-nextTariff (conf.nextTariff, "new tariff", false, false, GetStgLogger(), sd),
-address (conf.address, "address", false, false, GetStgLogger(), sd),
-note (conf.note, "note", false, false, GetStgLogger(), sd),
-group (conf.group, "group", false, false, GetStgLogger(), sd),
-email (conf.email, "email", false, false, GetStgLogger(), sd),
-phone (conf.phone, "phone", false, false, GetStgLogger(), sd),
-realName (conf.realName, "realName", false, false, GetStgLogger(), sd),
-credit (conf.credit, "credit", false, false, GetStgLogger(), sd),
-creditExpire(conf.creditExpire, "creditExpire", false, false, GetStgLogger(), sd),
-ips (conf.ips, "IP", false, false, GetStgLogger(), sd),
-userdata0 (conf.userdata[0], "userdata0", false, false, GetStgLogger(), sd),
-userdata1 (conf.userdata[1], "userdata1", false, false, GetStgLogger(), sd),
-userdata2 (conf.userdata[2], "userdata2", false, false, GetStgLogger(), sd),
-userdata3 (conf.userdata[3], "userdata3", false, false, GetStgLogger(), sd),
-userdata4 (conf.userdata[4], "userdata4", false, false, GetStgLogger(), sd),
-userdata5 (conf.userdata[5], "userdata5", false, false, GetStgLogger(), sd),
-userdata6 (conf.userdata[6], "userdata6", false, false, GetStgLogger(), sd),
-userdata7 (conf.userdata[7], "userdata7", false, false, GetStgLogger(), sd),
-userdata8 (conf.userdata[8], "userdata8", false, false, GetStgLogger(), sd),
-userdata9 (conf.userdata[9], "userdata9", false, false, GetStgLogger(), sd)
-{
-}
-//-----------------------------------------------------------------------------
+ password (conf.password, "password", true, false, GetStgLogger(), sd),
+ passive (conf.passive, "passive", false, false, GetStgLogger(), sd),
+ disabled (conf.disabled, "disabled", false, false, GetStgLogger(), sd),
+ disabledDetailStat(conf.disabledDetailStat, "DisabledDetailStat", false, false, GetStgLogger(), sd),
+ alwaysOnline(conf.alwaysOnline, "alwaysOnline", false, false, GetStgLogger(), sd),
+ tariffName (conf.tariffName, "tariff", false, false, GetStgLogger(), sd),
+ nextTariff (conf.nextTariff, "new tariff", false, false, GetStgLogger(), sd),
+ address (conf.address, "address", false, false, GetStgLogger(), sd),
+ note (conf.note, "note", false, false, GetStgLogger(), sd),
+ group (conf.group, "group", false, false, GetStgLogger(), sd),
+ email (conf.email, "email", false, false, GetStgLogger(), sd),
+ phone (conf.phone, "phone", false, false, GetStgLogger(), sd),
+ realName (conf.realName, "realName", false, false, GetStgLogger(), sd),
+ credit (conf.credit, "credit", false, false, GetStgLogger(), sd),
+ creditExpire(conf.creditExpire, "creditExpire", false, false, GetStgLogger(), sd),
+ ips (conf.ips, "IP", false, false, GetStgLogger(), sd),
+ userdata0 (conf.userdata[0], "userdata0", false, false, GetStgLogger(), sd),
+ userdata1 (conf.userdata[1], "userdata1", false, false, GetStgLogger(), sd),
+ userdata2 (conf.userdata[2], "userdata2", false, false, GetStgLogger(), sd),
+ userdata3 (conf.userdata[3], "userdata3", false, false, GetStgLogger(), sd),
+ userdata4 (conf.userdata[4], "userdata4", false, false, GetStgLogger(), sd),
+ userdata5 (conf.userdata[5], "userdata5", false, false, GetStgLogger(), sd),
+ userdata6 (conf.userdata[6], "userdata6", false, false, GetStgLogger(), sd),
+ userdata7 (conf.userdata[7], "userdata7", false, false, GetStgLogger(), sd),
+ userdata8 (conf.userdata[8], "userdata8", false, false, GetStgLogger(), sd),
+ userdata9 (conf.userdata[9], "userdata9", false, false, GetStgLogger(), sd)
+{}
#endif
#include <pthread.h>
+
#include <csignal>
#include <cassert>
#include <algorithm>
: USERS(),
users(),
usersToDelete(),
- userIPNotifiersBefore(),
- userIPNotifiersAfter(),
+ /*userIPNotifiersBefore(),
+ userIPNotifiersAfter(),*/
ipIndex(),
loginIndex(),
settings(s),
users.push_front(u);
AddUserIntoIndexes(users.begin());
-SetUserNotifiers(users.begin());
{
// Fire all "on add" notifiers
login.c_str());
return;
}
+
+ u->SetDeleted();
}
{
STG_LOCKER lock(&mutex, __FILE__, __LINE__);
u->OnDelete();
- u->SetDeleted();
USER_TO_DEL utd;
utd.iter = u;
utd.delTime = stgTime;
usersToDelete.push_back(utd);
- UnSetUserNotifiers(u);
DelUserFromIndexes(u);
WriteServLog("%s User \'%s\' deleted.",
}
}
//-----------------------------------------------------------------------------
+bool USERS_IMPL::Authorize(const std::string & login, uint32_t ip,
+ uint32_t enabledDirs, const AUTH * auth)
+{
+user_iter iter;
+STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+if (FindByNameNonLock(login, &iter))
+ {
+ WriteServLog("Attempt to authorize non-existant user '%s'", login.c_str());
+ return false;
+ }
+
+if (FindByIPIdx(ip, iter))
+ {
+ if (iter->GetLogin() != login)
+ {
+ WriteServLog("Attempt to authorize user '%s' from ip %s which already occupied by '%s'",
+ login.c_str(), inet_ntostring(ip).c_str(),
+ iter->GetLogin().c_str());
+ return false;
+ }
+ if (iter->Authorize(ip, enabledDirs, auth))
+ return false;
+ return true;
+ }
+
+if (iter->Authorize(ip, enabledDirs, auth))
+ return false;
+
+AddToIPIdx(iter);
+return true;
+}
+//-----------------------------------------------------------------------------
+bool USERS_IMPL::Unauthorize(const std::string & login, const AUTH * auth)
+{
+user_iter iter;
+STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+if (FindByNameNonLock(login, &iter))
+ {
+ WriteServLog("Attempt to unauthorize non-existant user '%s'", login.c_str());
+ return false;
+ }
+
+uint32_t ip = iter->GetCurrIP();
+
+iter->Unauthorize(auth);
+
+if (!iter->GetAuthorized())
+ DelFromIPIdx(ip);
+
+return true;
+}
+//-----------------------------------------------------------------------------
int USERS_IMPL::ReadUsers()
{
vector<string> usersList;
ui = users.begin();
AddUserIntoIndexes(ui);
- SetUserNotifiers(ui);
if (ui->ReadConf() < 0)
return -1;
//-----------------------------------------------------------------------------
void * USERS_IMPL::Run(void * d)
{
+sigset_t signalSet;
+sigfillset(&signalSet);
+pthread_sigmask(SIG_BLOCK, &signalSet, NULL);
+
printfd(__FILE__, "=====================| pid: %d |===================== \n", getpid());
USERS_IMPL * us = (USERS_IMPL*) d;
user_iter ui = us->users.begin();
while (ui != us->users.end())
{
- us->UnSetUserNotifiers(ui);
us->DelUserFromIndexes(ui);
++ui;
}
return;
}
//-----------------------------------------------------------------------------
-int USERS_IMPL::GetUserNum() const
-{
-return users.size();
-}
-//-----------------------------------------------------------------------------
void USERS_IMPL::AddToIPIdx(user_iter user)
{
printfd(__FILE__, "USERS: Add IP Idx\n");
ipIndex.find(ip)
);
-//assert(it != ipIndex.end() && "User is in index");
if (it == ipIndex.end())
- return; // User has not been added
+ return;
ipIndex.erase(it);
}
//-----------------------------------------------------------------------------
+bool USERS_IMPL::FindByIPIdx(uint32_t ip, user_iter & iter) const
+{
+map<uint32_t, user_iter>::const_iterator it(ipIndex.find(ip));
+if (it == ipIndex.end())
+ return false;
+iter = it->second;
+return true;
+}
+//-----------------------------------------------------------------------------
int USERS_IMPL::FindByIPIdx(uint32_t ip, USER_PTR * usr) const
{
- USER_IMPL * ptr = NULL;
- if (FindByIPIdx(ip, &ptr))
- return -1;
- *usr = ptr;
+STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+
+user_iter iter;
+if (FindByIPIdx(ip, iter))
+ {
+ *usr = &(*iter);
return 0;
+ }
+
+return -1;
}
//-----------------------------------------------------------------------------
int USERS_IMPL::FindByIPIdx(uint32_t ip, USER_IMPL ** usr) const
{
STG_LOCKER lock(&mutex, __FILE__, __LINE__);
-map<uint32_t, user_iter>::const_iterator it;
-it = ipIndex.find(ip);
-
-if (it == ipIndex.end())
+user_iter iter;
+if (FindByIPIdx(ip, iter))
{
- //printfd(__FILE__, "User NOT found in IP_Index!!!\n");
- return -1;
+ *usr = &(*iter);
+ return 0;
}
-*usr = &(*it->second);
-//printfd(__FILE__, "User found in IP_Index\n");
-return 0;
+
+return -1;
}
//-----------------------------------------------------------------------------
bool USERS_IMPL::IsIPInIndex(uint32_t ip) const
{
STG_LOCKER lock(&mutex, __FILE__, __LINE__);
-map<uint32_t, user_iter>::const_iterator it;
-it = ipIndex.find(ip);
+map<uint32_t, user_iter>::const_iterator it(ipIndex.find(ip));
return it != ipIndex.end();
}
return -1;
}
//-----------------------------------------------------------------------------
-void USERS_IMPL::SetUserNotifiers(user_iter user)
-{
-STG_LOCKER lock(&mutex, __FILE__, __LINE__);
-
-PROPERTY_NOTIFER_IP_BEFORE nb(*this, user);
-PROPERTY_NOTIFER_IP_AFTER na(*this, user);
-
-userIPNotifiersBefore.push_front(nb);
-userIPNotifiersAfter.push_front(na);
-
-user->AddCurrIPBeforeNotifier(&(*userIPNotifiersBefore.begin()));
-user->AddCurrIPAfterNotifier(&(*userIPNotifiersAfter.begin()));
-}
-//-----------------------------------------------------------------------------
-void USERS_IMPL::UnSetUserNotifiers(user_iter user)
-{
-STG_LOCKER lock(&mutex, __FILE__, __LINE__);
-
-list<PROPERTY_NOTIFER_IP_BEFORE>::iterator bi;
-list<PROPERTY_NOTIFER_IP_AFTER>::iterator ai;
-
-bi = userIPNotifiersBefore.begin();
-while (bi != userIPNotifiersBefore.end())
- {
- if (bi->GetUser() == user)
- {
- bi->GetUser()->DelCurrIPBeforeNotifier(&(*bi));
- userIPNotifiersBefore.erase(bi);
- //printfd(__FILE__, "Notifier Before removed. User %s\n", bi->GetUser()->GetLogin().c_str());
- break;
- }
- ++bi;
- }
-
-ai = userIPNotifiersAfter.begin();
-while (ai != userIPNotifiersAfter.end())
- {
- if (ai->GetUser() == user)
- {
- ai->GetUser()->DelCurrIPAfterNotifier(&(*ai));
- userIPNotifiersAfter.erase(ai);
- //printfd(__FILE__, "Notifier After removed. User %s\n", ai->GetUser()->GetLogin().c_str());
- break;
- }
- ++ai;
- }
-}
-//-----------------------------------------------------------------------------
void USERS_IMPL::AddUserIntoIndexes(user_iter user)
{
STG_LOCKER lock(&mutex, __FILE__, __LINE__);
class USERS_IMPL;
//-----------------------------------------------------------------------------
-class PROPERTY_NOTIFER_IP_BEFORE: public PROPERTY_NOTIFIER_BASE<uint32_t> {
-public:
- PROPERTY_NOTIFER_IP_BEFORE(USERS_IMPL & us, user_iter u) : users(us), user(u) {}
- void Notify(const uint32_t & oldValue, const uint32_t & newValue);
- user_iter GetUser() const { return user; }
-private:
- USERS_IMPL & users;
- user_iter user;
-};
-//-----------------------------------------------------------------------------
-class PROPERTY_NOTIFER_IP_AFTER: public PROPERTY_NOTIFIER_BASE<uint32_t> {
-public:
- PROPERTY_NOTIFER_IP_AFTER(USERS_IMPL & us, user_iter u) : users(us), user(u) {}
- void Notify(const uint32_t & oldValue, const uint32_t & newValue);
- user_iter GetUser() const { return user; }
-private:
- USERS_IMPL & users;
- user_iter user;
-};
-//-----------------------------------------------------------------------------
struct USER_TO_DEL {
USER_TO_DEL()
: iter(),
int Add(const std::string & login, const ADMIN * admin);
void Del(const std::string & login, const ADMIN * admin);
+ bool Authorize(const std::string & login, uint32_t ip,
+ uint32_t enabledDirs, const AUTH * auth);
+ bool Unauthorize(const std::string & login, const AUTH * auth);
+
int ReadUsers();
- int GetUserNum() const;
+ size_t Count() const { return users.size(); }
int FindByIPIdx(uint32_t ip, USER_PTR * user) const;
int FindByIPIdx(uint32_t ip, USER_IMPL ** user) const;
int Stop();
private:
+ USERS_IMPL(const USERS_IMPL & rvalue);
+ USERS_IMPL & operator=(const USERS_IMPL & rvalue);
+
void AddToIPIdx(user_iter user);
void DelFromIPIdx(uint32_t ip);
+ bool FindByIPIdx(uint32_t ip, user_iter & iter) const;
int FindByNameNonLock(const std::string & login, user_iter * user);
void RealDelUser();
void ProcessActions();
- void SetUserNotifiers(user_iter user);
- void UnSetUserNotifiers(user_iter user);
-
void AddUserIntoIndexes(user_iter user);
void DelUserFromIndexes(user_iter user);
std::list<USER_IMPL> users;
std::list<USER_TO_DEL> usersToDelete;
- std::list<PROPERTY_NOTIFER_IP_BEFORE> userIPNotifiersBefore;
- std::list<PROPERTY_NOTIFER_IP_AFTER> userIPNotifiersAfter;
std::map<uint32_t, user_iter> ipIndex;
std::map<std::string, user_iter> loginIndex;
std::set<NOTIFIER_BASE<USER_IMPL_PTR>*> onDelNotifiersImpl;
};
//-----------------------------------------------------------------------------
-inline
+/*inline
void PROPERTY_NOTIFER_IP_BEFORE::Notify(const uint32_t & oldValue,
const uint32_t &)
{
//EVENT_LOOP_SINGLETON::GetInstance().Enqueue(users, &USERS::AddToIPIdx, user);
// Using explicit call to assure that index is valid, because fast reconnect with delayed call can result in authorization error
users.AddToIPIdx(user);
-}
+}*/
//-----------------------------------------------------------------------------
#endif
includes: all
clean: all
- rm -f $(DIR_LIB)/*
install: all
uninstall: all
-
include ../../Makefile.conf
-PROG = lib$(LIB_NAME).so
+PROG = lib$(LIB_NAME).a
-ifeq ($(PROT), on)
-DEFS += -DLINPROT
-endif
-
-ifeq ($(DEMO), on)
-DEFS += -DDEMO
-endif
-
-ifeq ($(OS), bsd)
- ifeq ($(PROT), on)
- DEFS += -DFREEBDSPROT
- endif
-MAKE = gmake
-endif
-
-ifeq ($(OS), bsd5)
- ifeq ($(PROT), on)
- DEFS += -DFREEBDSPROT
- endif
-MAKE = gmake
-endif
+SEARCH_DIRS = -I ../../include -I . -I ./include
ifeq ($(STG_TIME), yes)
DEFS += -DSTG_TIME
endif
-ifneq ($(ADD_DEFS),)
-DEFS += $(ADD_DEFS)
+ifneq ($(LIB_DEFS),)
+DEFS += $(LIB_DEFS)
endif
-SEARCH_DIRS = -I $(DIR_INCLUDE) -I ./
+ifneq ($(LIB_INCS),)
+SEARCH_DIRS += $(LIB_INCS)
+endif
OBJS = $(notdir $(patsubst %.cpp, %.o, $(patsubst %.c, %.o, $(SRCS))))
-INST_INCS = $(addprefix $(DIR_INCLUDE)/, $(notdir $(INCS)))
-INST_LIBS = $(DIR_LIB)/lib$(LIB_NAME)
-
-CXXFLAGS += -fPIC $(DEFS)
-LDFLAGS += -shared -Wl,-rpath,$(PREFIX)/usr/lib/stg
-
-vpath %.so $(DIR_LIB)
+CXXFLAGS += -fPIC $(SEARCH_DIRS) $(DEFS)
+CFLAGS += -fPIC $(SEARCH_DIRS) $(DEFS)
all: $(PROG)
-$(PROG): $(OBJS) $(STGLIBS)
- $(CXX) $(LDFLAGS) -Wl,-soname,$(PROG) $^ $(LIBS) -o $(PROG) -L $(DIR_LIB)
+$(PROG): $(OBJS)
ar rc lib$(LIB_NAME).a $(OBJS)
ranlib lib$(LIB_NAME).a
- cp *.so $(DIR_LIB)
- cp *.a $(DIR_LIB)
-
-includes: $(INCS)
- cp -p $(INCS) $(DIR_INCLUDE)/stg
clean:
rm -f deps $(PROG) *.o *.a *.so tags *.*~
- for file in $(INCS); do \
- rm -f $(DIR_INCLUDE)/stg/$$file; \
- done
install: $(PROG)
mkdir -m $(DIR_MODE) -p $(PREFIX)/usr/lib/stg
install -m $(BIN_MODE) -o $(OWNER) -s $(PROG) $(PREFIX)/usr/lib/stg/$(PROG)
mkdir -m $(DIR_MODE) -p $(PREFIX)/usr/include/stg
- install -m $(DATA_MODE) -o $(OWNER) $(INCS) $(PREFIX)/usr/include/stg/
+ install -m $(DATA_MODE) -o $(OWNER) $(addprefix include/stg/,$(INCS)) $(PREFIX)/usr/include/stg/
uninstall:
rm -f $(PREFIX)/usr/lib/stg/$(PROG)
deps: $(SRCS) ../../Makefile.conf
@>deps ;\
for file in $(SRCS); do\
- echo "`$(CC) $(CXXFLAGS) $(SEARCH_DIRS) $(DEFS) -MM $$file` Makefile ../../Makefile.conf" >> deps ;\
- echo -e '\t$$(CC) $(CXXFLAGS) $(SEARCH_DIRS) $(DEFS) -c $$<' >> deps ;\
+ echo "$$file" | grep ".c$$" > /dev/null;\
+ if [ $$? -eq 0 ];\
+ then\
+ echo "`$(CC) $(CFLAGS) -MM $$file` Makefile ../../Makefile.conf" >> deps ;\
+ printf '%b\n' '\t$$(CC) $(CFLAGS) -c $$<' >> deps ;\
+ else\
+ echo "`$(CXX) $(CXXFLAGS) -MM $$file` Makefile ../../Makefile.conf" >> deps ;\
+ printf '%b\n' '\t$$(CXX) $(CXXFLAGS) -c $$<' >> deps ;\
+ fi;\
done
-
$Author: faust $
*/
-
-/*#include <sys/stat.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-#include <stdio.h>
-#include <iconv.h>
-
-
-#include <stdarg.h>
-
-
+// For old and dub systems
+// Like FreeBSD4
#include <sys/types.h>
-#include <math.h>
-
-#ifdef WIN32
-#include <sysutils.hpp>
-#else
+#include <sys/time.h>
#include <unistd.h>
-#include <sys/wait.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <sys/socket.h>
-#endif*/
-#ifdef FREE_BSD
-#include <sys/types.h>
-#endif
+#include <sys/select.h>
#ifdef WIN32
#include <winsock2.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
+#include <sys/select.h>
#endif
#include <iconv.h>
#include <cerrno>
#include <cassert>
-#include "common.h"
+#include "stg/common.h"
#ifndef INET_ADDRSTRLEN
# define INET_ADDRSTRLEN 16
return dst;
}
-//---------------------------------------------------------------------------
+
+int ParseYesNo(const std::string & str, bool * val)
+{
+if (0 == strncasecmp(str.c_str(), "yes", 3))
+ {
+ *val = true;
+ return 0;
+ }
+
+if (0 == strncasecmp(str.c_str(), "no", 2))
+ {
+ *val = false;
+ return 0;
+ }
+
+return -1;
+}
+
+int ParseInt(const std::string & str, int * val)
+{
+if (str2x<int>(str, *val))
+ return -1;
+return 0;
+}
+
+int ParseUnsigned(const string & str, unsigned * val)
+{
+if (str2x<unsigned>(str, *val))
+ return -1;
+return 0;
+}
+
+int ParseIntInRange(const string & str, int min, int max, int * val)
+{
+if (ParseInt(str, val) != 0)
+ return -1;
+
+if (*val < min || *val > max)
+ return -1;
+
+return 0;
+}
+
+int ParseUnsignedInRange(const string & str, unsigned min,
+ unsigned max, unsigned * val)
+{
+if (ParseUnsigned(str, val) != 0)
+ return -1;
+
+if (*val < min || *val > max)
+ return -1;
+
+return 0;
+}
+
+bool WaitPackets(int sd)
+{
+fd_set rfds;
+FD_ZERO(&rfds);
+FD_SET(sd, &rfds);
+
+struct timeval tv;
+tv.tv_sec = 0;
+tv.tv_usec = 500000;
+
+int res = select(sd + 1, &rfds, NULL, NULL, &tv);
+if (res == -1) // Error
+ {
+ if (errno != EINTR)
+ printfd(__FILE__, "Error on select: '%s'\n", strerror(errno));
+ return false;
+ }
+
+if (res == 0) // Timeout
+ return false;
+
+return true;
+}
+++ /dev/null
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/*
- * Author : Boris Mikhailenko <stg34@stargazer.dp.ua>
- */
-
- /*
- $Revision: 1.32 $
- $Date: 2010/11/08 10:11:19 $
- $Author: faust $
- */
-
-#ifndef common_h
-#define common_h
-
-#ifdef __BORLANDC__
-#include <time.h>
-#else
-#include <ctime>
-#endif
-#include <string>
-
-#include "stg/os_int.h"
-#include "stg/const.h"
-
-#define STAT_TIME_3 (1)
-#define STAT_TIME_2 (2)
-#define STAT_TIME_1 (3)
-#define STAT_TIME_1_2 (4)
-#define STAT_TIME_1_4 (5)
-#define STAT_TIME_1_6 (6)
-
-#define FN_STR_LEN (NAME_MAX)
-
-#define ST_F 0
-#define ST_B 1
-#define ST_KB 2
-#define ST_MB 3
-
-//-----------------------------------------------------------------------------
-const char * IntToKMG(long long a, int statType = ST_F);
-const char * LogDate(time_t t);
-int ParesTimeStat(const char * str);
-int IsTimeStat(struct tm * t, int statTime);
-/*bool IsDigit(char c);
-bool IsAlpha(char c);*/
-int strtodouble2(const char * s, double &a);
-int printfd(const char * __file__, const char * fmt, ...);
-void Encode12(char * dst, const char * src, size_t srcLen);
-void Decode21(char * dst, const char * src);
-
-void Encode12str(std::string & dst, const std::string & src);
-void Decode21str(std::string & dst, const std::string & src);
-
-int ParseIPString(const char * str, uint32_t * ips, int maxIP);
-void KOIToWin(const char * s1, char * s2, int l);
-void WinToKOI(const char * s1, char * s2, int l);
-void KOIToWin(const std::string & s1, std::string * s2);
-void WinToKOI(const std::string & s1, std::string * s2);
-int DaysInMonth(unsigned year, unsigned mon);
-int DaysInCurrentMonth();
-int Min8(int a);
-//char * inet_ntostr(unsigned long);
-std::string inet_ntostring(uint32_t);
-uint32_t inet_strington(const std::string & value);
-int strprintf(std::string * str, const char * fmt, ...);
-int ParseTariffTimeStr(const char * str, int &h1, int &m1, int &h2, int &m2);
-uint32_t CalcMask(uint32_t msk);
-void TouchFile(const std::string & fileName);
-#ifdef WIN32
-void EncodeStr(char * str, unsigned long serial, int useHDD);
-void DecodeStr(char * str, unsigned long serial, int useHDD);
-#endif //WIN32
-void SwapBytes(uint16_t & value);
-void SwapBytes(uint32_t & value);
-void SwapBytes(uint64_t & value);
-void SwapBytes(int16_t & value);
-void SwapBytes(int32_t & value);
-void SwapBytes(int64_t & value);
-
-std::string & TrimL(std::string & val);
-std::string & TrimR(std::string & val);
-std::string & Trim(std::string & val);
-
-std::string IconvString(const std::string & source, const std::string & from, const std::string & to);
-
-//-----------------------------------------------------------------------------
-template <typename varT>
-int str2x(const std::string & str, varT & x)
-{
- int pos = 0;
- int minus = 1;
-
- if (str.empty())
- return -1;
-
- if (str[0] == '+')
- pos++;
-
- if (str[0] == '-')
- {
- pos++;
- minus = -1;
- }
-
- if ((str[pos] < '0' || str[pos] > '9'))
- return -1;
-
- x = str[pos++] - '0';
-
- for (unsigned i = pos; i < str.size(); i++)
- {
- if ((str[i] < '0' || str[i] > '9'))
- return -1;
-
- x *= 10;
- x += str[i] - '0';
- }
-
- x*= minus;
-
- return 0;
-}
-//-----------------------------------------------------------------------------
-template <typename varT>
-const std::string & x2str(varT x, std::string & s)
-{
- varT xx = x;
- int pos = 1;
-
- x /= 10;
- while (x != 0)
- {
- x /= 10;
- pos++;
- }
-
- if (xx < 0)
- {
- pos++;
- s.resize(pos, 0);
- s[0] = '-';
- }
- else if (xx > 0)
- {
- s.resize(pos, 0);
- }
- else
- {
- s.resize(1, 0);
- s[0] = '0';
- return s;
- }
-
- x = xx;
-
- while (x != 0)
- {
- if (x < 0)
- s[--pos] = -(x % 10) + '0';
- else
- s[--pos] = x % 10 + '0';
-
- x /= 10;
- }
-
- return s;
-}
-//-----------------------------------------------------------------------------
-template <typename varT>
-const std::string & unsigned2str(varT x, std::string & s)
-{
- varT xx = x;
- int pos = 1;
-
- x /= 10;
- while (x != 0)
- {
- x /= 10;
- pos++;
- }
-
- if (xx > 0)
- {
- s.resize(pos, 0);
- }
- else
- {
- s.resize(1, 0);
- s[0] = '0';
- return s;
- }
-
- x = xx;
-
- while (x != 0)
- {
- s[--pos] = x % 10 + '0';
-
- x /= 10;
- }
-
- return s;
-}
-//-----------------------------------------------------------------------------
-int str2x(const std::string & str, int & x);
-int str2x(const std::string & str, unsigned & x);
-int str2x(const std::string & str, long & x);
-int str2x(const std::string & str, unsigned long & x);
-#ifndef WIN32
-int str2x(const std::string & str, long long & x);
-int str2x(const std::string & str, unsigned long long & x);
-#endif
-//-----------------------------------------------------------------------------
-const std::string & x2str(unsigned x, std::string & s);
-const std::string & x2str(unsigned long x, std::string & s);
-const std::string & x2str(unsigned long long x, std::string & s);
-//-----------------------------------------------------------------------------
-char * stg_strptime(const char *, const char *, struct tm *);
-time_t stg_timegm(struct tm *);
-
-#endif
--- /dev/null
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Author : Boris Mikhailenko <stg34@stargazer.dp.ua>
+ */
+
+ /*
+ $Revision: 1.32 $
+ $Date: 2010/11/08 10:11:19 $
+ $Author: faust $
+ */
+
+#ifndef common_h
+#define common_h
+
+#ifdef __BORLANDC__
+#include <time.h>
+#else
+#include <ctime>
+#endif
+#include <string>
+
+#include "stg/os_int.h"
+#include "stg/const.h"
+
+#define STAT_TIME_3 (1)
+#define STAT_TIME_2 (2)
+#define STAT_TIME_1 (3)
+#define STAT_TIME_1_2 (4)
+#define STAT_TIME_1_4 (5)
+#define STAT_TIME_1_6 (6)
+
+#define FN_STR_LEN (NAME_MAX)
+
+#define ST_F 0
+#define ST_B 1
+#define ST_KB 2
+#define ST_MB 3
+
+//-----------------------------------------------------------------------------
+const char * IntToKMG(long long a, int statType = ST_F);
+const char * LogDate(time_t t);
+int ParesTimeStat(const char * str);
+int IsTimeStat(struct tm * t, int statTime);
+/*bool IsDigit(char c);
+bool IsAlpha(char c);*/
+int strtodouble2(const char * s, double &a);
+int printfd(const char * __file__, const char * fmt, ...);
+void Encode12(char * dst, const char * src, size_t srcLen);
+void Decode21(char * dst, const char * src);
+
+void Encode12str(std::string & dst, const std::string & src);
+void Decode21str(std::string & dst, const std::string & src);
+
+int ParseIPString(const char * str, uint32_t * ips, int maxIP);
+void KOIToWin(const char * s1, char * s2, int l);
+void WinToKOI(const char * s1, char * s2, int l);
+void KOIToWin(const std::string & s1, std::string * s2);
+void WinToKOI(const std::string & s1, std::string * s2);
+int DaysInMonth(unsigned year, unsigned mon);
+int DaysInCurrentMonth();
+int Min8(int a);
+//char * inet_ntostr(unsigned long);
+std::string inet_ntostring(uint32_t);
+uint32_t inet_strington(const std::string & value);
+int strprintf(std::string * str, const char * fmt, ...);
+int ParseTariffTimeStr(const char * str, int &h1, int &m1, int &h2, int &m2);
+uint32_t CalcMask(uint32_t msk);
+void TouchFile(const std::string & fileName);
+#ifdef WIN32
+void EncodeStr(char * str, unsigned long serial, int useHDD);
+void DecodeStr(char * str, unsigned long serial, int useHDD);
+#endif //WIN32
+void SwapBytes(uint16_t & value);
+void SwapBytes(uint32_t & value);
+void SwapBytes(uint64_t & value);
+void SwapBytes(int16_t & value);
+void SwapBytes(int32_t & value);
+void SwapBytes(int64_t & value);
+
+std::string & TrimL(std::string & val);
+std::string & TrimR(std::string & val);
+std::string & Trim(std::string & val);
+
+std::string IconvString(const std::string & source, const std::string & from, const std::string & to);
+
+int ParseInt(const std::string & str, int * val);
+int ParseUnsigned(const std::string & str, unsigned * val);
+int ParseIntInRange(const std::string & str, int min, int max, int * val);
+int ParseUnsignedInRange(const std::string & str, unsigned min,
+ unsigned max, unsigned * val);
+int ParseYesNo(const std::string & str, bool * val);
+
+bool WaitPackets(int sd);
+
+template <typename varT>
+int str2x(const std::string & str, varT & x);
+template <typename varT>
+const std::string & x2str(varT x, std::string & s);
+template <typename varT>
+const std::string & unsigned2str(varT x, std::string & s);
+
+//-----------------------------------------------------------------------------
+template <typename varT>
+inline
+int str2x(const std::string & str, varT & x)
+{
+ int pos = 0;
+ int minus = 1;
+
+ if (str.empty())
+ return -1;
+
+ if (str[0] == '+')
+ pos++;
+
+ if (str[0] == '-')
+ {
+ pos++;
+ minus = -1;
+ }
+
+ if ((str[pos] < '0' || str[pos] > '9'))
+ return -1;
+
+ x = str[pos++] - '0';
+
+ for (unsigned i = pos; i < str.size(); i++)
+ {
+ if ((str[i] < '0' || str[i] > '9'))
+ return -1;
+
+ x *= 10;
+ x += str[i] - '0';
+ }
+
+ x*= minus;
+
+ return 0;
+}
+//-----------------------------------------------------------------------------
+template <typename varT>
+inline
+const std::string & x2str(varT x, std::string & s)
+{
+ varT xx = x;
+ int pos = 1;
+
+ x /= 10;
+ while (x != 0)
+ {
+ x /= 10;
+ pos++;
+ }
+
+ if (xx < 0)
+ {
+ pos++;
+ s.resize(pos, 0);
+ s[0] = '-';
+ }
+ else if (xx > 0)
+ {
+ s.resize(pos, 0);
+ }
+ else
+ {
+ s.resize(1, 0);
+ s[0] = '0';
+ return s;
+ }
+
+ x = xx;
+
+ while (x != 0)
+ {
+ if (x < 0)
+ s[--pos] = -(x % 10) + '0';
+ else
+ s[--pos] = x % 10 + '0';
+
+ x /= 10;
+ }
+
+ return s;
+}
+//-----------------------------------------------------------------------------
+template <typename varT>
+inline
+const std::string & unsigned2str(varT x, std::string & s)
+{
+ varT xx = x;
+ int pos = 1;
+
+ x /= 10;
+ while (x != 0)
+ {
+ x /= 10;
+ pos++;
+ }
+
+ if (xx > 0)
+ {
+ s.resize(pos, 0);
+ }
+ else
+ {
+ s.resize(1, 0);
+ s[0] = '0';
+ return s;
+ }
+
+ x = xx;
+
+ while (x != 0)
+ {
+ s[--pos] = x % 10 + '0';
+
+ x /= 10;
+ }
+
+ return s;
+}
+//-----------------------------------------------------------------------------
+int str2x(const std::string & str, int & x);
+int str2x(const std::string & str, unsigned & x);
+int str2x(const std::string & str, long & x);
+int str2x(const std::string & str, unsigned long & x);
+#ifndef WIN32
+int str2x(const std::string & str, long long & x);
+int str2x(const std::string & str, unsigned long long & x);
+#endif
+//-----------------------------------------------------------------------------
+const std::string & x2str(unsigned x, std::string & s);
+const std::string & x2str(unsigned long x, std::string & s);
+const std::string & x2str(unsigned long long x, std::string & s);
+//-----------------------------------------------------------------------------
+char * stg_strptime(const char *, const char *, struct tm *);
+time_t stg_timegm(struct tm *);
+
+#endif
#include <fstream>
-#include "conffiles.h"
-#include "stg/common.h"
+#include "stg/conffiles.h"
using namespace std;
error = 0;
return e;
}
-/*//---------------------------------------------------------------------------
-int CONFIGFILE::ReadString(const string & param, char * str, int * maxLen, const char * defaultVal) const
-{
-it = param_val.find(param);
-// îÁÛÌÉ ÎÕÖÎÕÀ ÐÅÒÅÍÅÎÎÕÀ
-
-if (it != param_val.end())
- {
- // þÔÏ-ÔÏ ÓÔÏÉÔ
- strncpy(str, param_val[param].c_str(), *maxLen);
- *maxLen = param_val[param].size();
- return 0;
- }
-
-strncpy(str, defaultVal, *maxLen);
-*maxLen = strlen(defaultVal);
-return -1;
-}*/
//---------------------------------------------------------------------------
int CONFIGFILE::ReadString(const string & param, string * val, const string & defaultVal) const
{
const map<string, string>::const_iterator it(param_val.find(param));
-// îÁÛÌÉ ÎÕÖÎÕÀ ÐÅÒÅÍÅÎÎÕÀ
if (it != param_val.end())
{
- // þÔÏ-ÔÏ ÓÔÏÉÔ
*val = it->second;
return 0;
}
int CONFIGFILE::ReadInt(const string & param, int * val, int defaultVal) const
{
const map<string, string>::const_iterator it(param_val.find(param));
-// îÁÛÌÉ ÎÕÖÎÕÀ ÐÅÒÅÍÅÎÎÕÀ
if (it != param_val.end())
{
- // þÔÏ-ÔÏ ÓÔÏÉÔ
char *res;
*val = strtol(it->second.c_str(), &res, 10);
if (*res != 0)
int CONFIGFILE::ReadUInt(const string & param, unsigned int * val, unsigned int defaultVal) const
{
const map<string, string>::const_iterator it(param_val.find(param));
-// îÁÛÌÉ ÎÕÖÎÕÀ ÐÅÒÅÍÅÎÎÕÀ
if (it != param_val.end())
{
- // þÔÏ-ÔÏ ÓÔÏÉÔ
char *res;
*val = strtoul(it->second.c_str(), &res, 10);
if (*res != 0)
int CONFIGFILE::ReadLongInt(const string & param, long int * val, long int defaultVal) const
{
const map<string, string>::const_iterator it(param_val.find(param));
-// îÁÛÌÉ ÎÕÖÎÕÀ ÐÅÒÅÍÅÎÎÕÀ
if (it != param_val.end())
{
- // þÔÏ-ÔÏ ÓÔÏÉÔ
char *res;
*val = strtol(it->second.c_str(), &res, 10);
if (*res != 0)
int CONFIGFILE::ReadULongInt(const string & param, unsigned long int * val, unsigned long int defaultVal) const
{
const map<string, string>::const_iterator it(param_val.find(param));
-// îÁÛÌÉ ÎÕÖÎÕÀ ÐÅÒÅÍÅÎÎÕÀ
if (it != param_val.end())
{
- // þÔÏ-ÔÏ ÓÔÏÉÔ
char *res;
*val = strtoul(it->second.c_str(), &res, 10);
if (*res != 0)
int CONFIGFILE::ReadLongLongInt(const string & param, int64_t * val, int64_t defaultVal) const
{
const map<string, string>::const_iterator it(param_val.find(param));
-// îÁÛÌÉ ÎÕÖÎÕÀ ÐÅÒÅÍÅÎÎÕÀ
if (it != param_val.end())
{
- // þÔÏ-ÔÏ ÓÔÏÉÔ
char *res;
*val = strtoll(it->second.c_str(), &res, 10);
if (*res != 0)
int CONFIGFILE::ReadULongLongInt(const string & param, uint64_t * val, uint64_t defaultVal) const
{
const map<string, string>::const_iterator it(param_val.find(param));
-// îÁÛÌÉ ÎÕÖÎÕÀ ÐÅÒÅÍÅÎÎÕÀ
if (it != param_val.end())
{
- // þÔÏ-ÔÏ ÓÔÏÉÔ
char *res;
*val = strtoull(it->second.c_str(), &res, 10);
if (*res != 0)
int CONFIGFILE::ReadShortInt(const string & param, short int * val, short int defaultVal) const
{
const map<string, string>::const_iterator it(param_val.find(param));
-// îÁÛÌÉ ÎÕÖÎÕÀ ÐÅÒÅÍÅÎÎÕÀ
if (it != param_val.end())
{
- // þÔÏ-ÔÏ ÓÔÏÉÔ
char *res;
*val = (short)strtol(it->second.c_str(), &res, 10);
if (*res != 0)
int CONFIGFILE::ReadUShortInt(const string & param, unsigned short int * val, unsigned short int defaultVal) const
{
const map<string, string>::const_iterator it(param_val.find(param));
-// îÁÛÌÉ ÎÕÖÎÕÀ ÐÅÒÅÍÅÎÎÕÀ
if (it != param_val.end())
{
- // þÔÏ-ÔÏ ÓÔÏÉÔ
char *res;
*val = (short)strtoul(it->second.c_str(), &res, 10);
if (*res != 0)
//---------------------------------------------------------------------------
void CONFIGFILE::WriteInt(const string & param, int64_t val)
{
-string s;
-x2str(val, s);
-param_val[param] = s;
+char buf[32];
+snprintf(buf, sizeof(buf), "%lld", static_cast<long long int>(val));
+param_val[param] = buf;
changed = true;
}
//---------------------------------------------------------------------------
int CONFIGFILE::ReadDouble(const string & param, double * val, double defaultVal) const
{
const map<string, string>::const_iterator it(param_val.find(param));
-// îÁÛÌÉ ÎÕÖÎÕÀ ÐÅÒÅÍÅÎÎÕÀ
if (it != param_val.end())
{
- // þÔÏ-ÔÏ ÓÔÏÉÔ
char *res;
*val = strtod(it->second.c_str(), &res);
if (*res != 0)
if (!changed)
return 0;
-std::string pid;
-x2str(getpid(), pid);
+char pid[6];
+snprintf(pid, sizeof(pid), "%d", getpid());
if (Flush(fileName + "." + pid))
return -1;
+++ /dev/null
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/*
- * Date: 27.10.2002
- */
-
-/*
- * Author : Boris Mikhailenko <stg34@ua.fm>
- */
-
-/*
- $Revision: 1.5 $
- $Date: 2009/06/22 16:00:38 $
- */
-
-//---------------------------------------------------------------------------
-
-#ifndef ConfFilesH
-#define ConfFilesH
-
-#include <map>
-#include <string>
-
-#include "stg/os_int.h"
-
-using namespace std;
-//---------------------------------------------------------------------------
-
-typedef bool (*StringCaseCmp_t)(const string & str1, const string & str2);
-
-class CONFIGFILE
-{
-public:
- CONFIGFILE(const string & fn, bool nook = false);
- ~CONFIGFILE();
- const string & GetFileName() const;
-
- // æÕÎËÃÉÉ Read* ×ÏÚ×ÒÁÝÁÀÔ 0 ÐÒÉ ÕÓÐÅÛÎÏÍ ÓÞÉÔÙ×ÁÎÉÉ
- // É EINVAL ÐÒÉ ÏÔÓÕÔÓ×ÉÉ ÐÁÒÁÍÅÔÒÁ É ×ÙÓÔÁ×ÌÑÀÔ defaulValue
- //int ReadString(const string & param, char * val, int * maxLen, const char * defaultVal) const;
- int ReadString(const string & param, string * val, const string & defaultVal) const;
- int ReadTime(const string & param, time_t *, time_t) const;
- int ReadShortInt(const string & param, short int *, short int) const;
- int ReadInt(const string & param, int *, int) const;
- int ReadLongInt(const string & param, long int *, long int) const;
- int ReadLongLongInt(const string & param, int64_t *, int64_t) const;
- int ReadUShortInt(const string & param, unsigned short int *, unsigned short int) const;
- int ReadUInt(const string & param, unsigned int *, unsigned int) const;
- int ReadULongInt(const string & param, unsigned long int *, unsigned long int) const;
- int ReadULongLongInt(const string & param, uint64_t *, uint64_t) const;
- int ReadDouble(const string & param, double * val, double defaultVal) const;
-
- void WriteString(const string & param, const char * val) { return WriteString(param, std::string(val)); }
- void WriteString(const string & param, const string & val);
- void WriteInt(const string & param, int64_t val);
- void WriteDouble(const string & param, double val);
-
- int Error() const;
- int Flush() const;
-
-private:
- map<string, string, StringCaseCmp_t> param_val;
- string fileName;
- mutable int error;
- mutable bool changed;
-
- int Flush(const std::string & path) const;
-};
-//---------------------------------------------------------------------------
-#endif
--- /dev/null
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Date: 27.10.2002
+ */
+
+/*
+ * Author : Boris Mikhailenko <stg34@ua.fm>
+ */
+
+/*
+ $Revision: 1.5 $
+ $Date: 2009/06/22 16:00:38 $
+ */
+
+//---------------------------------------------------------------------------
+
+#ifndef ConfFilesH
+#define ConfFilesH
+
+#include <map>
+#include <string>
+
+#include "stg/os_int.h"
+
+using namespace std;
+//---------------------------------------------------------------------------
+
+typedef bool (*StringCaseCmp_t)(const string & str1, const string & str2);
+
+class CONFIGFILE
+{
+public:
+ CONFIGFILE(const string & fn, bool nook = false);
+ ~CONFIGFILE();
+ const string & GetFileName() const;
+
+ // æÕÎËÃÉÉ Read* ×ÏÚ×ÒÁÝÁÀÔ 0 ÐÒÉ ÕÓÐÅÛÎÏÍ ÓÞÉÔÙ×ÁÎÉÉ
+ // É EINVAL ÐÒÉ ÏÔÓÕÔÓ×ÉÉ ÐÁÒÁÍÅÔÒÁ É ×ÙÓÔÁ×ÌÑÀÔ defaulValue
+ //int ReadString(const string & param, char * val, int * maxLen, const char * defaultVal) const;
+ int ReadString(const string & param, string * val, const string & defaultVal) const;
+ int ReadTime(const string & param, time_t *, time_t) const;
+ int ReadShortInt(const string & param, short int *, short int) const;
+ int ReadInt(const string & param, int *, int) const;
+ int ReadLongInt(const string & param, long int *, long int) const;
+ int ReadLongLongInt(const string & param, int64_t *, int64_t) const;
+ int ReadUShortInt(const string & param, unsigned short int *, unsigned short int) const;
+ int ReadUInt(const string & param, unsigned int *, unsigned int) const;
+ int ReadULongInt(const string & param, unsigned long int *, unsigned long int) const;
+ int ReadULongLongInt(const string & param, uint64_t *, uint64_t) const;
+ int ReadDouble(const string & param, double * val, double defaultVal) const;
+
+ void WriteString(const string & param, const char * val) { return WriteString(param, std::string(val)); }
+ void WriteString(const string & param, const string & val);
+ void WriteInt(const string & param, int64_t val);
+ void WriteDouble(const string & param, double val);
+
+ int Error() const;
+ int Flush() const;
+
+private:
+ map<string, string, StringCaseCmp_t> param_val;
+ string fileName;
+ mutable int error;
+ mutable bool changed;
+
+ int Flush(const std::string & path) const;
+};
+//---------------------------------------------------------------------------
+#endif
LIB_NAME = stgcrypto
-SRCS = ag_md5.cpp \
- blowfish.cpp
+SRCS = ag_md5.c \
+ blowfish.c
INCS = ag_md5.h \
blowfish.h
--- /dev/null
+#ifdef WIN32
+#include <process.h>
+#include <windows.h>
+#else
+#include <sys/time.h>
+#include <unistd.h>
+#endif
+
+#include <time.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "stg/ag_md5.h"
+
+#define F1(x, y, z) (z ^ (x & (y ^ z)))
+#define F2(x, y, z) F1(z, x, y)
+#define F3(x, y, z) (x ^ y ^ z)
+#define F4(x, y, z) (y ^ (x | ~z))
+
+#define MD5STEP(f, w, x, y, z, data, s) \
+ ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
+
+int i64c(int i)
+{
+ if (i <= 0)
+ return ('.');
+
+ if (i == 1)
+ return ('/');
+
+ if (i >= 2 && i < 12)
+ return ('0' - 2 + i);
+
+ if (i >= 12 && i < 38)
+ return ('A' - 12 + i);
+
+ if (i >= 38 && i < 63)
+ return ('a' - 38 + i);
+
+ return ('z');
+}
+
+char * l64a_(long l)
+{
+ static char buf[8];
+ int i = 0;
+
+ if (l < 0L)
+ return ((char *) 0);
+
+ do {
+ buf[i++] = i64c ((int) (l % 64));
+ buf[i] = '\0';
+ } while (l /= 64L, l > 0 && i < 6);
+
+ return (buf);
+}
+
+char * crypt_make_salt(void)
+{
+
+ static char result[40];
+ #ifdef WIN32
+ unsigned int tsec;
+ #else
+ struct timeval tv;
+ #endif
+
+ result[0] = '\0';
+ strcpy(result, "$1$"); /* magic for the new MD5 crypt() */
+
+ /*
+ * Generate 8 chars of salt, the old crypt() will use only first 2.
+ */
+ #ifdef WIN32
+ strcat(result, l64a_(GetTickCount()));
+ tsec = time(NULL);
+ strcat(result, l64a_(tsec + getpid() + clock()));
+ #else
+ gettimeofday(&tv, (struct timezone *) 0);
+ strcat(result, l64a_(tv.tv_usec));
+ strcat(result, l64a_(tv.tv_sec + getpid() + clock()));
+ #endif
+
+ if (strlen(result) > 3 + 8) /* magic+salt */
+ result[11] = '\0';
+
+ return result;
+}
+
+void byteReverse(unsigned char *buf, unsigned longs)
+{
+ uint32_t t;
+ do {
+ t = (uint32_t) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
+ ((unsigned) buf[1] << 8 | buf[0]);
+ *(uint32_t *) buf = t;
+ buf += 4;
+ } while (--longs);
+}
+
+/*
+ * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
+ * initialization constants.
+ */
+void MD5Init(struct MD5Context *ctx)
+{
+ ctx->buf[0] = 0x67452301;
+ ctx->buf[1] = 0xefcdab89;
+ ctx->buf[2] = 0x98badcfe;
+ ctx->buf[3] = 0x10325476;
+
+ ctx->bits[0] = 0;
+ ctx->bits[1] = 0;
+}
+
+/*
+ * Update context to reflect the concatenation of another buffer full
+ * of bytes.
+ */
+void MD5Update(struct MD5Context *ctx, char const *buf, unsigned len)
+{
+ uint32_t t;
+
+ /* Update bitcount */
+
+ t = ctx->bits[0];
+ if ((ctx->bits[0] = t + ((uint32_t) len << 3)) < t)
+ ctx->bits[1]++; /* Carry from low to high */
+ ctx->bits[1] += len >> 29;
+
+ t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
+
+ /* Handle any leading odd-sized chunks */
+
+ if (t) {
+ unsigned char *p = (unsigned char *) ctx->in + t;
+
+ t = 64 - t;
+ if (len < t) {
+ memcpy(p, buf, len);
+ return;
+ }
+ memcpy(p, buf, t);
+ byteReverse(ctx->in, 16);
+ MD5Transform(ctx->buf, (uint32_t *) ctx->in);
+ buf += t;
+ len -= t;
+ }
+ /* Process data in 64-byte chunks */
+
+ while (len >= 64) {
+ memcpy(ctx->in, buf, 64);
+ byteReverse(ctx->in, 16);
+ MD5Transform(ctx->buf, (uint32_t *) ctx->in);
+ buf += 64;
+ len -= 64;
+ }
+
+ /* Handle any remaining bytes of data. */
+
+ memcpy(ctx->in, buf, len);
+}
+
+/*
+ * Final wrapup - pad to 64-byte boundary with the bit pattern
+ * 1 0* (64-bit count of bits processed, MSB-first)
+ */
+void
+MD5Final(unsigned char digest[16], struct MD5Context *ctx)
+{
+ unsigned count;
+ unsigned char *p;
+
+ /* Compute number of bytes mod 64 */
+ count = (ctx->bits[0] >> 3) & 0x3F;
+
+ /* Set the first char of padding to 0x80. This is safe since there is
+ always at least one byte free */
+ p = ctx->in + count;
+ *p++ = 0x80;
+
+ /* Bytes of padding needed to make 64 bytes */
+ count = 64 - 1 - count;
+
+ /* Pad out to 56 mod 64 */
+ if (count < 8) {
+ /* Two lots of padding: Pad the first block to 64 bytes */
+ memset(p, 0, count);
+ byteReverse(ctx->in, 16);
+ MD5Transform(ctx->buf, (uint32_t *) ctx->in);
+
+ /* Now fill the next block with 56 bytes */
+ memset(ctx->in, 0, 56);
+ } else {
+ /* Pad block to 56 bytes */
+ memset(p, 0, count - 8);
+ }
+ byteReverse(ctx->in, 14);
+
+ /* Append length in bits and transform */
+ ((uint32_t *) ctx->in)[14] = ctx->bits[0];
+ ((uint32_t *) ctx->in)[15] = ctx->bits[1];
+
+ MD5Transform(ctx->buf, (uint32_t *) ctx->in);
+ byteReverse((unsigned char *) ctx->buf, 4);
+ memcpy(digest, ctx->buf, 16);
+ memset((char *) ctx, 0, sizeof(ctx)); /* In case it's sensitive */
+}
+
+/*
+ * The core of the MD5 algorithm, this alters an existing MD5 hash to
+ * reflect the addition of 16 longwords of new data. MD5Update blocks
+ * the data and converts bytes into longwords for this routine.
+ */
+void
+MD5Transform(uint32_t buf[4], uint32_t const in[16])
+{
+ register uint32_t a, b, c, d;
+
+ a = buf[0];
+ b = buf[1];
+ c = buf[2];
+ d = buf[3];
+
+ MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
+ MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
+ MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
+ MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
+ MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
+ MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
+ MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
+ MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
+ MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
+ MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
+ MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
+ MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
+ MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
+ MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
+ MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
+ MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
+
+ MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
+ MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
+ MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
+ MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
+ MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
+ MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
+ MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
+ MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
+ MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
+ MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
+ MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
+ MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
+ MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
+ MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
+ MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
+ MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
+
+ MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
+ MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
+ MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
+ MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
+ MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
+ MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
+ MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
+ MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
+ MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
+ MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
+ MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
+ MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
+ MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
+ MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
+ MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
+ MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
+
+ MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
+ MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
+ MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
+ MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
+ MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
+ MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
+ MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
+ MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
+ MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
+ MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
+ MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
+ MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
+ MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
+ MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
+ MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
+ MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
+
+ buf[0] += a;
+ buf[1] += b;
+ buf[2] += c;
+ buf[3] += d;
+}
+
+static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */
+ "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+static void
+to64(char *s, unsigned long v, int n)
+{
+ while (--n >= 0) {
+ *s++ = itoa64[v&0x3f];
+ v >>= 6;
+ }
+}
+
+/*
+ * UNIX password
+ *
+ * Use MD5 for what it is best at...
+ */
+
+char *
+libshadow_md5_crypt(const char *pw, const char *salt)
+{
+ static const char *magic = "$1$"; /*
+ * This string is magic for
+ * this algorithm. Having
+ * it this way, we can get
+ * get better later on
+ */
+ static char passwd[120], *p;
+ static const char *sp,*ep;
+ unsigned char final[16];
+ int sl,pl,i,j;
+ MD5_CTX ctx,ctx1;
+ unsigned long l;
+
+ /* Refine the Salt first */
+ sp = salt;
+
+ /* If it starts with the magic string, then skip that */
+ if(!strncmp(sp,magic,strlen(magic)))
+ sp += strlen(magic);
+
+ /* It stops at the first '$', max 8 chars */
+ for(ep=sp;*ep && *ep != '$' && ep < (sp+8);ep++)
+ continue;
+
+ /* get the length of the true salt */
+ sl = ep - sp;
+
+ MD5Init(&ctx);
+
+ /* The password first, since that is what is most unknown */
+ MD5Update(&ctx, pw, strlen(pw));
+
+ /* Then our magic string */
+ MD5Update(&ctx, magic, strlen(magic));
+
+ /* Then the raw salt */
+ MD5Update(&ctx, sp, sl);
+
+ /* Then just as many characters of the MD5(pw,salt,pw) */
+ MD5Init(&ctx1);
+ MD5Update(&ctx1,pw,strlen(pw));
+ MD5Update(&ctx1,sp,sl);
+ MD5Update(&ctx1,pw,strlen(pw));
+ MD5Final(final,&ctx1);
+ for(pl = strlen(pw); pl > 0; pl -= 16)
+ MD5Update(&ctx, (char*)final, pl>16 ? 16 : pl);
+
+ /* Don't leave anything around in vm they could use. */
+ memset(final,0,sizeof final);
+
+ /* Then something really weird... */
+ for (j=0,i = strlen(pw); i ; i >>= 1)
+ if(i&1)
+ MD5Update(&ctx, (char*)final+j, 1);
+ else
+ MD5Update(&ctx, pw+j, 1);
+
+ /* Now make the output string */
+ strcpy(passwd,magic);
+ strncat(passwd,sp,sl);
+ strcat(passwd,"$");
+
+ MD5Final(final,&ctx);
+
+ /*
+ * and now, just to make sure things don't run too fast
+ * On a 60 Mhz Pentium this takes 34 msec, so you would
+ * need 30 seconds to build a 1000 entry dictionary...
+ */
+ /*
+ for(i=0;i<1000;i++) {
+ MD5Init(&ctx1);
+ if(i & 1)
+ MD5Update(&ctx1,pw,strlen(pw));
+ else
+ MD5Update(&ctx1,final,16);
+
+ if(i % 3)
+ MD5Update(&ctx1,sp,sl);
+
+ if(i % 7)
+ MD5Update(&ctx1,pw,strlen(pw));
+
+ if(i & 1)
+ MD5Update(&ctx1,final,16);
+ else
+ MD5Update(&ctx1,pw,strlen(pw));
+ MD5Final(final,&ctx1);
+ }*/
+
+ p = passwd + strlen(passwd);
+
+ l = (final[ 0]<<16) | (final[ 6]<<8) | final[12]; to64(p,l,4); p += 4;
+ l = (final[ 1]<<16) | (final[ 7]<<8) | final[13]; to64(p,l,4); p += 4;
+ l = (final[ 2]<<16) | (final[ 8]<<8) | final[14]; to64(p,l,4); p += 4;
+ l = (final[ 3]<<16) | (final[ 9]<<8) | final[15]; to64(p,l,4); p += 4;
+ l = (final[ 4]<<16) | (final[10]<<8) | final[ 5]; to64(p,l,4); p += 4;
+ l = final[11] ; to64(p,l,2); p += 2;
+ *p = '\0';
+
+ /* Don't leave anything around in vm they could use. */
+ memset(final,0,sizeof final);
+
+ return passwd;
+}
+
+char *pw_encrypt(const char *clear, const char *salt) {
+
+ /*
+ * If the salt string from the password file or from crypt_make_salt()
+ * begins with the magic string, use the new algorithm.
+ */
+ if (strncmp(salt, "$1$", 3) == 0)
+ return(libshadow_md5_crypt(clear, salt));
+ else return(NULL);
+
+}
+/* AG MD5 functions */
+char *make_ag_hash(time_t salt, const char *clear) {
+ char salt_str[20];
+ char *res=NULL;
+ char *p;
+
+ unsigned long slt = salt;
+ sprintf(salt_str, "$1$%08lx", slt);
+ res=libshadow_md5_crypt(clear, salt_str);
+ p=strrchr(res, '$');
+ return(++p);
+}
+
+int check_ag_hash(time_t salt, const char *clear, const char *hash) {
+ return(strcmp(hash, make_ag_hash(salt, clear)));
+}
+
+++ /dev/null
-
-#ifdef WIN32
-#include <process.h>
-#include <windows.h>
-#else
-#include <sys/time.h>
-#include <unistd.h>
-#endif
-
-#include <time.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "ag_md5.h"
-
-
-#define F1(x, y, z) (z ^ (x & (y ^ z)))
-#define F2(x, y, z) F1(z, x, y)
-#define F3(x, y, z) (x ^ y ^ z)
-#define F4(x, y, z) (y ^ (x | ~z))
-
-#define MD5STEP(f, w, x, y, z, data, s) \
- ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
-
-
-int i64c(int i)
-{
- if (i <= 0)
- return ('.');
-
- if (i == 1)
- return ('/');
-
- if (i >= 2 && i < 12)
- return ('0' - 2 + i);
-
- if (i >= 12 && i < 38)
- return ('A' - 12 + i);
-
- if (i >= 38 && i < 63)
- return ('a' - 38 + i);
-
- return ('z');
-}
-
-char * l64a_(long l)
-{
- static char buf[8];
- int i = 0;
-
- if (l < 0L)
- return ((char *) 0);
-
- do {
- buf[i++] = i64c ((int) (l % 64));
- buf[i] = '\0';
- } while (l /= 64L, l > 0 && i < 6);
-
- return (buf);
-}
-
-char * crypt_make_salt(void)
-{
-
- static char result[40];
- #ifdef WIN32
- unsigned int tsec;
- #else
- struct timeval tv;
- #endif
-
- result[0] = '\0';
- strcpy(result, "$1$"); /* magic for the new MD5 crypt() */
-
- /*
- * Generate 8 chars of salt, the old crypt() will use only first 2.
- */
- #ifdef WIN32
- strcat(result, l64a_(GetTickCount()));
- tsec = time(NULL);
- strcat(result, l64a_(tsec + getpid() + clock()));
- #else
- gettimeofday(&tv, (struct timezone *) 0);
- strcat(result, l64a_(tv.tv_usec));
- strcat(result, l64a_(tv.tv_sec + getpid() + clock()));
- #endif
-
- if (strlen(result) > 3 + 8) /* magic+salt */
- result[11] = '\0';
-
- return result;
-}
-
-void byteReverse(unsigned char *buf, unsigned longs)
-{
- uint32_t t;
- do {
- t = (uint32_t) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
- ((unsigned) buf[1] << 8 | buf[0]);
- *(uint32_t *) buf = t;
- buf += 4;
- } while (--longs);
-}
-
-/*
- * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
- * initialization constants.
- */
-void MD5Init(struct MD5Context *ctx)
-{
- ctx->buf[0] = 0x67452301;
- ctx->buf[1] = 0xefcdab89;
- ctx->buf[2] = 0x98badcfe;
- ctx->buf[3] = 0x10325476;
-
- ctx->bits[0] = 0;
- ctx->bits[1] = 0;
-}
-
-/*
- * Update context to reflect the concatenation of another buffer full
- * of bytes.
- */
-void MD5Update(struct MD5Context *ctx, char const *buf, unsigned len)
-{
- uint32_t t;
-
- /* Update bitcount */
-
- t = ctx->bits[0];
- if ((ctx->bits[0] = t + ((uint32_t) len << 3)) < t)
- ctx->bits[1]++; /* Carry from low to high */
- ctx->bits[1] += len >> 29;
-
- t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
-
- /* Handle any leading odd-sized chunks */
-
- if (t) {
- unsigned char *p = (unsigned char *) ctx->in + t;
-
- t = 64 - t;
- if (len < t) {
- memcpy(p, buf, len);
- return;
- }
- memcpy(p, buf, t);
- byteReverse(ctx->in, 16);
- MD5Transform(ctx->buf, (uint32_t *) ctx->in);
- buf += t;
- len -= t;
- }
- /* Process data in 64-byte chunks */
-
- while (len >= 64) {
- memcpy(ctx->in, buf, 64);
- byteReverse(ctx->in, 16);
- MD5Transform(ctx->buf, (uint32_t *) ctx->in);
- buf += 64;
- len -= 64;
- }
-
- /* Handle any remaining bytes of data. */
-
- memcpy(ctx->in, buf, len);
-}
-
-/*
- * Final wrapup - pad to 64-byte boundary with the bit pattern
- * 1 0* (64-bit count of bits processed, MSB-first)
- */
-void
-MD5Final(unsigned char digest[16], struct MD5Context *ctx)
-{
- unsigned count;
- unsigned char *p;
-
- /* Compute number of bytes mod 64 */
- count = (ctx->bits[0] >> 3) & 0x3F;
-
- /* Set the first char of padding to 0x80. This is safe since there is
- always at least one byte free */
- p = ctx->in + count;
- *p++ = 0x80;
-
- /* Bytes of padding needed to make 64 bytes */
- count = 64 - 1 - count;
-
- /* Pad out to 56 mod 64 */
- if (count < 8) {
- /* Two lots of padding: Pad the first block to 64 bytes */
- memset(p, 0, count);
- byteReverse(ctx->in, 16);
- MD5Transform(ctx->buf, (uint32_t *) ctx->in);
-
- /* Now fill the next block with 56 bytes */
- memset(ctx->in, 0, 56);
- } else {
- /* Pad block to 56 bytes */
- memset(p, 0, count - 8);
- }
- byteReverse(ctx->in, 14);
-
- /* Append length in bits and transform */
- ((uint32_t *) ctx->in)[14] = ctx->bits[0];
- ((uint32_t *) ctx->in)[15] = ctx->bits[1];
-
- MD5Transform(ctx->buf, (uint32_t *) ctx->in);
- byteReverse((unsigned char *) ctx->buf, 4);
- memcpy(digest, ctx->buf, 16);
- memset((char *) ctx, 0, sizeof(ctx)); /* In case it's sensitive */
-}
-
-/*
- * The core of the MD5 algorithm, this alters an existing MD5 hash to
- * reflect the addition of 16 longwords of new data. MD5Update blocks
- * the data and converts bytes into longwords for this routine.
- */
-void
-MD5Transform(uint32_t buf[4], uint32_t const in[16])
-{
- register uint32_t a, b, c, d;
-
- a = buf[0];
- b = buf[1];
- c = buf[2];
- d = buf[3];
-
- MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
- MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
- MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
- MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
- MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
- MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
- MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
- MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
- MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
- MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
- MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
- MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
- MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
- MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
- MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
- MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
-
- MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
- MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
- MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
- MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
- MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
- MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
- MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
- MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
- MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
- MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
- MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
- MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
- MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
- MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
- MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
- MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
-
- MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
- MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
- MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
- MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
- MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
- MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
- MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
- MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
- MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
- MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
- MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
- MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
- MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
- MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
- MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
- MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
-
- MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
- MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
- MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
- MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
- MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
- MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
- MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
- MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
- MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
- MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
- MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
- MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
- MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
- MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
- MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
- MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
-
- buf[0] += a;
- buf[1] += b;
- buf[2] += c;
- buf[3] += d;
-}
-
-static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */
- "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
-
-static void
-to64(char *s, unsigned long v, int n)
-{
- while (--n >= 0) {
- *s++ = itoa64[v&0x3f];
- v >>= 6;
- }
-}
-
-/*
- * UNIX password
- *
- * Use MD5 for what it is best at...
- */
-
-char *
-libshadow_md5_crypt(const char *pw, const char *salt)
-{
- static const char *magic = "$1$"; /*
- * This string is magic for
- * this algorithm. Having
- * it this way, we can get
- * get better later on
- */
- static char passwd[120], *p;
- static const char *sp,*ep;
- unsigned char final[16];
- int sl,pl,i,j;
- MD5_CTX ctx,ctx1;
- unsigned long l;
-
- /* Refine the Salt first */
- sp = salt;
-
- /* If it starts with the magic string, then skip that */
- if(!strncmp(sp,magic,strlen(magic)))
- sp += strlen(magic);
-
- /* It stops at the first '$', max 8 chars */
- for(ep=sp;*ep && *ep != '$' && ep < (sp+8);ep++)
- continue;
-
- /* get the length of the true salt */
- sl = ep - sp;
-
- MD5Init(&ctx);
-
- /* The password first, since that is what is most unknown */
- MD5Update(&ctx, pw, strlen(pw));
-
- /* Then our magic string */
- MD5Update(&ctx, magic, strlen(magic));
-
- /* Then the raw salt */
- MD5Update(&ctx, sp, sl);
-
- /* Then just as many characters of the MD5(pw,salt,pw) */
- MD5Init(&ctx1);
- MD5Update(&ctx1,pw,strlen(pw));
- MD5Update(&ctx1,sp,sl);
- MD5Update(&ctx1,pw,strlen(pw));
- MD5Final(final,&ctx1);
- for(pl = strlen(pw); pl > 0; pl -= 16)
- MD5Update(&ctx, (char*)final, pl>16 ? 16 : pl);
-
- /* Don't leave anything around in vm they could use. */
- memset(final,0,sizeof final);
-
- /* Then something really weird... */
- for (j=0,i = strlen(pw); i ; i >>= 1)
- if(i&1)
- MD5Update(&ctx, (char*)final+j, 1);
- else
- MD5Update(&ctx, pw+j, 1);
-
- /* Now make the output string */
- strcpy(passwd,magic);
- strncat(passwd,sp,sl);
- strcat(passwd,"$");
-
- MD5Final(final,&ctx);
-
- /*
- * and now, just to make sure things don't run too fast
- * On a 60 Mhz Pentium this takes 34 msec, so you would
- * need 30 seconds to build a 1000 entry dictionary...
- */
- /*
- for(i=0;i<1000;i++) {
- MD5Init(&ctx1);
- if(i & 1)
- MD5Update(&ctx1,pw,strlen(pw));
- else
- MD5Update(&ctx1,final,16);
-
- if(i % 3)
- MD5Update(&ctx1,sp,sl);
-
- if(i % 7)
- MD5Update(&ctx1,pw,strlen(pw));
-
- if(i & 1)
- MD5Update(&ctx1,final,16);
- else
- MD5Update(&ctx1,pw,strlen(pw));
- MD5Final(final,&ctx1);
- }*/
-
- p = passwd + strlen(passwd);
-
- l = (final[ 0]<<16) | (final[ 6]<<8) | final[12]; to64(p,l,4); p += 4;
- l = (final[ 1]<<16) | (final[ 7]<<8) | final[13]; to64(p,l,4); p += 4;
- l = (final[ 2]<<16) | (final[ 8]<<8) | final[14]; to64(p,l,4); p += 4;
- l = (final[ 3]<<16) | (final[ 9]<<8) | final[15]; to64(p,l,4); p += 4;
- l = (final[ 4]<<16) | (final[10]<<8) | final[ 5]; to64(p,l,4); p += 4;
- l = final[11] ; to64(p,l,2); p += 2;
- *p = '\0';
-
- /* Don't leave anything around in vm they could use. */
- memset(final,0,sizeof final);
-
- return passwd;
-}
-
-char *pw_encrypt(const char *clear, const char *salt) {
-
- /*
- * If the salt string from the password file or from crypt_make_salt()
- * begins with the magic string, use the new algorithm.
- */
- if (strncmp(salt, "$1$", 3) == 0)
- return(libshadow_md5_crypt(clear, salt));
- else return(NULL);
-
-}
-/* AG MD5 functions */
-char *make_ag_hash(time_t salt, const char *clear) {
- char salt_str[20];
- char *res=NULL;
- char *p;
-
- unsigned long slt = salt;
- sprintf(salt_str, "$1$%08lx", slt);
- res=libshadow_md5_crypt(clear, salt_str);
- p=strrchr(res, '$');
- return(++p);
-}
-
-int check_ag_hash(time_t salt, const char *clear, const char *hash) {
- return(strcmp(hash, make_ag_hash(salt, clear)));
-}
-
+++ /dev/null
-#ifndef _MD5_H
-#define _MD5_H
-
-#include <ctime>
-
-#include "stg/os_int.h"
-
-struct MD5Context {
- uint32_t buf[4];
- uint32_t bits[2];
- unsigned char in[64];
-};
-
-typedef struct MD5Context MD5_CTX;
-
-char *crypt_make_salt(void);
-void byteReverse(unsigned char*, unsigned);
-void MD5Init(struct MD5Context *ctx);
-void MD5Update(struct MD5Context*, char const*, unsigned);
-void MD5Final(unsigned char digest[16], struct MD5Context *ctx);
-void MD5Transform(uint32_t buf[4], uint32_t const in[16]);
-/* static void to64(char*, unsigned long, int); */
-char *libshadow_md5_crypt(const char*, const char*);
-char *pw_encrypt(const char*, const char*);
-
-/* AG functions */
-char *make_ag_hash(time_t salt, const char *clear);
-int check_ag_hash(time_t salt, const char *clear, const char *hash);
-
-#endif /* _MD5_H */
--- /dev/null
+/*
+ * Author : Paul Kocher
+ * E-mail : pck@netcom.com
+ * Date : 1997
+ * Description: C implementation of the Blowfish algorithm.
+ */
+
+#include <string.h>
+
+#include "stg/const.h"
+#include "stg/blowfish.h"
+
+#define ENCRYPT 0
+#define DECRYPT 1
+
+#define endianBig ((unsigned char) 0x45)
+#define endianLittle ((unsigned char) 0x54)
+
+#define MIN(a,b) ((a) < (b) ? a : b)
+
+#ifdef WIN32 /* Win32 doesn't have random() or lstat */
+ #define random() rand()
+ #define initstate(x,y,z) srand(x)
+ #define lstat(x,y) stat(x,y)
+#endif
+
+#ifndef S_ISREG
+ #define S_ISREG(x) ( ((x)&S_IFMT)==S_IFREG )
+#endif
+
+
+#define N 16
+
+static uint32_t F(BLOWFISH_CTX *ctx, uint32_t x);
+static const uint32_t ORIG_P[16 + 2] = {
+0x243F6A88L, 0x85A308D3L, 0x13198A2EL, 0x03707344L,
+0xA4093822L, 0x299F31D0L, 0x082EFA98L, 0xEC4E6C89L,
+0x452821E6L, 0x38D01377L, 0xBE5466CFL, 0x34E90C6CL,
+0xC0AC29B7L, 0xC97C50DDL, 0x3F84D5B5L, 0xB5470917L,
+0x9216D5D9L, 0x8979FB1BL
+};
+
+static const uint32_t ORIG_S[4][256] = {
+{ 0xD1310BA6L, 0x98DFB5ACL, 0x2FFD72DBL, 0xD01ADFB7L,
+ 0xB8E1AFEDL, 0x6A267E96L, 0xBA7C9045L, 0xF12C7F99L,
+ 0x24A19947L, 0xB3916CF7L, 0x0801F2E2L, 0x858EFC16L,
+ 0x636920D8L, 0x71574E69L, 0xA458FEA3L, 0xF4933D7EL,
+ 0x0D95748FL, 0x728EB658L, 0x718BCD58L, 0x82154AEEL,
+ 0x7B54A41DL, 0xC25A59B5L, 0x9C30D539L, 0x2AF26013L,
+ 0xC5D1B023L, 0x286085F0L, 0xCA417918L, 0xB8DB38EFL,
+ 0x8E79DCB0L, 0x603A180EL, 0x6C9E0E8BL, 0xB01E8A3EL,
+ 0xD71577C1L, 0xBD314B27L, 0x78AF2FDAL, 0x55605C60L,
+ 0xE65525F3L, 0xAA55AB94L, 0x57489862L, 0x63E81440L,
+ 0x55CA396AL, 0x2AAB10B6L, 0xB4CC5C34L, 0x1141E8CEL,
+ 0xA15486AFL, 0x7C72E993L, 0xB3EE1411L, 0x636FBC2AL,
+ 0x2BA9C55DL, 0x741831F6L, 0xCE5C3E16L, 0x9B87931EL,
+ 0xAFD6BA33L, 0x6C24CF5CL, 0x7A325381L, 0x28958677L,
+ 0x3B8F4898L, 0x6B4BB9AFL, 0xC4BFE81BL, 0x66282193L,
+ 0x61D809CCL, 0xFB21A991L, 0x487CAC60L, 0x5DEC8032L,
+ 0xEF845D5DL, 0xE98575B1L, 0xDC262302L, 0xEB651B88L,
+ 0x23893E81L, 0xD396ACC5L, 0x0F6D6FF3L, 0x83F44239L,
+ 0x2E0B4482L, 0xA4842004L, 0x69C8F04AL, 0x9E1F9B5EL,
+ 0x21C66842L, 0xF6E96C9AL, 0x670C9C61L, 0xABD388F0L,
+ 0x6A51A0D2L, 0xD8542F68L, 0x960FA728L, 0xAB5133A3L,
+ 0x6EEF0B6CL, 0x137A3BE4L, 0xBA3BF050L, 0x7EFB2A98L,
+ 0xA1F1651DL, 0x39AF0176L, 0x66CA593EL, 0x82430E88L,
+ 0x8CEE8619L, 0x456F9FB4L, 0x7D84A5C3L, 0x3B8B5EBEL,
+ 0xE06F75D8L, 0x85C12073L, 0x401A449FL, 0x56C16AA6L,
+ 0x4ED3AA62L, 0x363F7706L, 0x1BFEDF72L, 0x429B023DL,
+ 0x37D0D724L, 0xD00A1248L, 0xDB0FEAD3L, 0x49F1C09BL,
+ 0x075372C9L, 0x80991B7BL, 0x25D479D8L, 0xF6E8DEF7L,
+ 0xE3FE501AL, 0xB6794C3BL, 0x976CE0BDL, 0x04C006BAL,
+ 0xC1A94FB6L, 0x409F60C4L, 0x5E5C9EC2L, 0x196A2463L,
+ 0x68FB6FAFL, 0x3E6C53B5L, 0x1339B2EBL, 0x3B52EC6FL,
+ 0x6DFC511FL, 0x9B30952CL, 0xCC814544L, 0xAF5EBD09L,
+ 0xBEE3D004L, 0xDE334AFDL, 0x660F2807L, 0x192E4BB3L,
+ 0xC0CBA857L, 0x45C8740FL, 0xD20B5F39L, 0xB9D3FBDBL,
+ 0x5579C0BDL, 0x1A60320AL, 0xD6A100C6L, 0x402C7279L,
+ 0x679F25FEL, 0xFB1FA3CCL, 0x8EA5E9F8L, 0xDB3222F8L,
+ 0x3C7516DFL, 0xFD616B15L, 0x2F501EC8L, 0xAD0552ABL,
+ 0x323DB5FAL, 0xFD238760L, 0x53317B48L, 0x3E00DF82L,
+ 0x9E5C57BBL, 0xCA6F8CA0L, 0x1A87562EL, 0xDF1769DBL,
+ 0xD542A8F6L, 0x287EFFC3L, 0xAC6732C6L, 0x8C4F5573L,
+ 0x695B27B0L, 0xBBCA58C8L, 0xE1FFA35DL, 0xB8F011A0L,
+ 0x10FA3D98L, 0xFD2183B8L, 0x4AFCB56CL, 0x2DD1D35BL,
+ 0x9A53E479L, 0xB6F84565L, 0xD28E49BCL, 0x4BFB9790L,
+ 0xE1DDF2DAL, 0xA4CB7E33L, 0x62FB1341L, 0xCEE4C6E8L,
+ 0xEF20CADAL, 0x36774C01L, 0xD07E9EFEL, 0x2BF11FB4L,
+ 0x95DBDA4DL, 0xAE909198L, 0xEAAD8E71L, 0x6B93D5A0L,
+ 0xD08ED1D0L, 0xAFC725E0L, 0x8E3C5B2FL, 0x8E7594B7L,
+ 0x8FF6E2FBL, 0xF2122B64L, 0x8888B812L, 0x900DF01CL,
+ 0x4FAD5EA0L, 0x688FC31CL, 0xD1CFF191L, 0xB3A8C1ADL,
+ 0x2F2F2218L, 0xBE0E1777L, 0xEA752DFEL, 0x8B021FA1L,
+ 0xE5A0CC0FL, 0xB56F74E8L, 0x18ACF3D6L, 0xCE89E299L,
+ 0xB4A84FE0L, 0xFD13E0B7L, 0x7CC43B81L, 0xD2ADA8D9L,
+ 0x165FA266L, 0x80957705L, 0x93CC7314L, 0x211A1477L,
+ 0xE6AD2065L, 0x77B5FA86L, 0xC75442F5L, 0xFB9D35CFL,
+ 0xEBCDAF0CL, 0x7B3E89A0L, 0xD6411BD3L, 0xAE1E7E49L,
+ 0x00250E2DL, 0x2071B35EL, 0x226800BBL, 0x57B8E0AFL,
+ 0x2464369BL, 0xF009B91EL, 0x5563911DL, 0x59DFA6AAL,
+ 0x78C14389L, 0xD95A537FL, 0x207D5BA2L, 0x02E5B9C5L,
+ 0x83260376L, 0x6295CFA9L, 0x11C81968L, 0x4E734A41L,
+ 0xB3472DCAL, 0x7B14A94AL, 0x1B510052L, 0x9A532915L,
+ 0xD60F573FL, 0xBC9BC6E4L, 0x2B60A476L, 0x81E67400L,
+ 0x08BA6FB5L, 0x571BE91FL, 0xF296EC6BL, 0x2A0DD915L,
+ 0xB6636521L, 0xE7B9F9B6L, 0xFF34052EL, 0xC5855664L,
+ 0x53B02D5DL, 0xA99F8FA1L, 0x08BA4799L, 0x6E85076AL},
+
+{ 0x4B7A70E9L, 0xB5B32944L, 0xDB75092EL, 0xC4192623L,
+ 0xAD6EA6B0L, 0x49A7DF7DL, 0x9CEE60B8L, 0x8FEDB266L,
+ 0xECAA8C71L, 0x699A17FFL, 0x5664526CL, 0xC2B19EE1L,
+ 0x193602A5L, 0x75094C29L, 0xA0591340L, 0xE4183A3EL,
+ 0x3F54989AL, 0x5B429D65L, 0x6B8FE4D6L, 0x99F73FD6L,
+ 0xA1D29C07L, 0xEFE830F5L, 0x4D2D38E6L, 0xF0255DC1L,
+ 0x4CDD2086L, 0x8470EB26L, 0x6382E9C6L, 0x021ECC5EL,
+ 0x09686B3FL, 0x3EBAEFC9L, 0x3C971814L, 0x6B6A70A1L,
+ 0x687F3584L, 0x52A0E286L, 0xB79C5305L, 0xAA500737L,
+ 0x3E07841CL, 0x7FDEAE5CL, 0x8E7D44ECL, 0x5716F2B8L,
+ 0xB03ADA37L, 0xF0500C0DL, 0xF01C1F04L, 0x0200B3FFL,
+ 0xAE0CF51AL, 0x3CB574B2L, 0x25837A58L, 0xDC0921BDL,
+ 0xD19113F9L, 0x7CA92FF6L, 0x94324773L, 0x22F54701L,
+ 0x3AE5E581L, 0x37C2DADCL, 0xC8B57634L, 0x9AF3DDA7L,
+ 0xA9446146L, 0x0FD0030EL, 0xECC8C73EL, 0xA4751E41L,
+ 0xE238CD99L, 0x3BEA0E2FL, 0x3280BBA1L, 0x183EB331L,
+ 0x4E548B38L, 0x4F6DB908L, 0x6F420D03L, 0xF60A04BFL,
+ 0x2CB81290L, 0x24977C79L, 0x5679B072L, 0xBCAF89AFL,
+ 0xDE9A771FL, 0xD9930810L, 0xB38BAE12L, 0xDCCF3F2EL,
+ 0x5512721FL, 0x2E6B7124L, 0x501ADDE6L, 0x9F84CD87L,
+ 0x7A584718L, 0x7408DA17L, 0xBC9F9ABCL, 0xE94B7D8CL,
+ 0xEC7AEC3AL, 0xDB851DFAL, 0x63094366L, 0xC464C3D2L,
+ 0xEF1C1847L, 0x3215D908L, 0xDD433B37L, 0x24C2BA16L,
+ 0x12A14D43L, 0x2A65C451L, 0x50940002L, 0x133AE4DDL,
+ 0x71DFF89EL, 0x10314E55L, 0x81AC77D6L, 0x5F11199BL,
+ 0x043556F1L, 0xD7A3C76BL, 0x3C11183BL, 0x5924A509L,
+ 0xF28FE6EDL, 0x97F1FBFAL, 0x9EBABF2CL, 0x1E153C6EL,
+ 0x86E34570L, 0xEAE96FB1L, 0x860E5E0AL, 0x5A3E2AB3L,
+ 0x771FE71CL, 0x4E3D06FAL, 0x2965DCB9L, 0x99E71D0FL,
+ 0x803E89D6L, 0x5266C825L, 0x2E4CC978L, 0x9C10B36AL,
+ 0xC6150EBAL, 0x94E2EA78L, 0xA5FC3C53L, 0x1E0A2DF4L,
+ 0xF2F74EA7L, 0x361D2B3DL, 0x1939260FL, 0x19C27960L,
+ 0x5223A708L, 0xF71312B6L, 0xEBADFE6EL, 0xEAC31F66L,
+ 0xE3BC4595L, 0xA67BC883L, 0xB17F37D1L, 0x018CFF28L,
+ 0xC332DDEFL, 0xBE6C5AA5L, 0x65582185L, 0x68AB9802L,
+ 0xEECEA50FL, 0xDB2F953BL, 0x2AEF7DADL, 0x5B6E2F84L,
+ 0x1521B628L, 0x29076170L, 0xECDD4775L, 0x619F1510L,
+ 0x13CCA830L, 0xEB61BD96L, 0x0334FE1EL, 0xAA0363CFL,
+ 0xB5735C90L, 0x4C70A239L, 0xD59E9E0BL, 0xCBAADE14L,
+ 0xEECC86BCL, 0x60622CA7L, 0x9CAB5CABL, 0xB2F3846EL,
+ 0x648B1EAFL, 0x19BDF0CAL, 0xA02369B9L, 0x655ABB50L,
+ 0x40685A32L, 0x3C2AB4B3L, 0x319EE9D5L, 0xC021B8F7L,
+ 0x9B540B19L, 0x875FA099L, 0x95F7997EL, 0x623D7DA8L,
+ 0xF837889AL, 0x97E32D77L, 0x11ED935FL, 0x16681281L,
+ 0x0E358829L, 0xC7E61FD6L, 0x96DEDFA1L, 0x7858BA99L,
+ 0x57F584A5L, 0x1B227263L, 0x9B83C3FFL, 0x1AC24696L,
+ 0xCDB30AEBL, 0x532E3054L, 0x8FD948E4L, 0x6DBC3128L,
+ 0x58EBF2EFL, 0x34C6FFEAL, 0xFE28ED61L, 0xEE7C3C73L,
+ 0x5D4A14D9L, 0xE864B7E3L, 0x42105D14L, 0x203E13E0L,
+ 0x45EEE2B6L, 0xA3AAABEAL, 0xDB6C4F15L, 0xFACB4FD0L,
+ 0xC742F442L, 0xEF6ABBB5L, 0x654F3B1DL, 0x41CD2105L,
+ 0xD81E799EL, 0x86854DC7L, 0xE44B476AL, 0x3D816250L,
+ 0xCF62A1F2L, 0x5B8D2646L, 0xFC8883A0L, 0xC1C7B6A3L,
+ 0x7F1524C3L, 0x69CB7492L, 0x47848A0BL, 0x5692B285L,
+ 0x095BBF00L, 0xAD19489DL, 0x1462B174L, 0x23820E00L,
+ 0x58428D2AL, 0x0C55F5EAL, 0x1DADF43EL, 0x233F7061L,
+ 0x3372F092L, 0x8D937E41L, 0xD65FECF1L, 0x6C223BDBL,
+ 0x7CDE3759L, 0xCBEE7460L, 0x4085F2A7L, 0xCE77326EL,
+ 0xA6078084L, 0x19F8509EL, 0xE8EFD855L, 0x61D99735L,
+ 0xA969A7AAL, 0xC50C06C2L, 0x5A04ABFCL, 0x800BCADCL,
+ 0x9E447A2EL, 0xC3453484L, 0xFDD56705L, 0x0E1E9EC9L,
+ 0xDB73DBD3L, 0x105588CDL, 0x675FDA79L, 0xE3674340L,
+ 0xC5C43465L, 0x713E38D8L, 0x3D28F89EL, 0xF16DFF20L,
+ 0x153E21E7L, 0x8FB03D4AL, 0xE6E39F2BL, 0xDB83ADF7L},
+
+{ 0xE93D5A68L, 0x948140F7L, 0xF64C261CL, 0x94692934L,
+ 0x411520F7L, 0x7602D4F7L, 0xBCF46B2EL, 0xD4A20068L,
+ 0xD4082471L, 0x3320F46AL, 0x43B7D4B7L, 0x500061AFL,
+ 0x1E39F62EL, 0x97244546L, 0x14214F74L, 0xBF8B8840L,
+ 0x4D95FC1DL, 0x96B591AFL, 0x70F4DDD3L, 0x66A02F45L,
+ 0xBFBC09ECL, 0x03BD9785L, 0x7FAC6DD0L, 0x31CB8504L,
+ 0x96EB27B3L, 0x55FD3941L, 0xDA2547E6L, 0xABCA0A9AL,
+ 0x28507825L, 0x530429F4L, 0x0A2C86DAL, 0xE9B66DFBL,
+ 0x68DC1462L, 0xD7486900L, 0x680EC0A4L, 0x27A18DEEL,
+ 0x4F3FFEA2L, 0xE887AD8CL, 0xB58CE006L, 0x7AF4D6B6L,
+ 0xAACE1E7CL, 0xD3375FECL, 0xCE78A399L, 0x406B2A42L,
+ 0x20FE9E35L, 0xD9F385B9L, 0xEE39D7ABL, 0x3B124E8BL,
+ 0x1DC9FAF7L, 0x4B6D1856L, 0x26A36631L, 0xEAE397B2L,
+ 0x3A6EFA74L, 0xDD5B4332L, 0x6841E7F7L, 0xCA7820FBL,
+ 0xFB0AF54EL, 0xD8FEB397L, 0x454056ACL, 0xBA489527L,
+ 0x55533A3AL, 0x20838D87L, 0xFE6BA9B7L, 0xD096954BL,
+ 0x55A867BCL, 0xA1159A58L, 0xCCA92963L, 0x99E1DB33L,
+ 0xA62A4A56L, 0x3F3125F9L, 0x5EF47E1CL, 0x9029317CL,
+ 0xFDF8E802L, 0x04272F70L, 0x80BB155CL, 0x05282CE3L,
+ 0x95C11548L, 0xE4C66D22L, 0x48C1133FL, 0xC70F86DCL,
+ 0x07F9C9EEL, 0x41041F0FL, 0x404779A4L, 0x5D886E17L,
+ 0x325F51EBL, 0xD59BC0D1L, 0xF2BCC18FL, 0x41113564L,
+ 0x257B7834L, 0x602A9C60L, 0xDFF8E8A3L, 0x1F636C1BL,
+ 0x0E12B4C2L, 0x02E1329EL, 0xAF664FD1L, 0xCAD18115L,
+ 0x6B2395E0L, 0x333E92E1L, 0x3B240B62L, 0xEEBEB922L,
+ 0x85B2A20EL, 0xE6BA0D99L, 0xDE720C8CL, 0x2DA2F728L,
+ 0xD0127845L, 0x95B794FDL, 0x647D0862L, 0xE7CCF5F0L,
+ 0x5449A36FL, 0x877D48FAL, 0xC39DFD27L, 0xF33E8D1EL,
+ 0x0A476341L, 0x992EFF74L, 0x3A6F6EABL, 0xF4F8FD37L,
+ 0xA812DC60L, 0xA1EBDDF8L, 0x991BE14CL, 0xDB6E6B0DL,
+ 0xC67B5510L, 0x6D672C37L, 0x2765D43BL, 0xDCD0E804L,
+ 0xF1290DC7L, 0xCC00FFA3L, 0xB5390F92L, 0x690FED0BL,
+ 0x667B9FFBL, 0xCEDB7D9CL, 0xA091CF0BL, 0xD9155EA3L,
+ 0xBB132F88L, 0x515BAD24L, 0x7B9479BFL, 0x763BD6EBL,
+ 0x37392EB3L, 0xCC115979L, 0x8026E297L, 0xF42E312DL,
+ 0x6842ADA7L, 0xC66A2B3BL, 0x12754CCCL, 0x782EF11CL,
+ 0x6A124237L, 0xB79251E7L, 0x06A1BBE6L, 0x4BFB6350L,
+ 0x1A6B1018L, 0x11CAEDFAL, 0x3D25BDD8L, 0xE2E1C3C9L,
+ 0x44421659L, 0x0A121386L, 0xD90CEC6EL, 0xD5ABEA2AL,
+ 0x64AF674EL, 0xDA86A85FL, 0xBEBFE988L, 0x64E4C3FEL,
+ 0x9DBC8057L, 0xF0F7C086L, 0x60787BF8L, 0x6003604DL,
+ 0xD1FD8346L, 0xF6381FB0L, 0x7745AE04L, 0xD736FCCCL,
+ 0x83426B33L, 0xF01EAB71L, 0xB0804187L, 0x3C005E5FL,
+ 0x77A057BEL, 0xBDE8AE24L, 0x55464299L, 0xBF582E61L,
+ 0x4E58F48FL, 0xF2DDFDA2L, 0xF474EF38L, 0x8789BDC2L,
+ 0x5366F9C3L, 0xC8B38E74L, 0xB475F255L, 0x46FCD9B9L,
+ 0x7AEB2661L, 0x8B1DDF84L, 0x846A0E79L, 0x915F95E2L,
+ 0x466E598EL, 0x20B45770L, 0x8CD55591L, 0xC902DE4CL,
+ 0xB90BACE1L, 0xBB8205D0L, 0x11A86248L, 0x7574A99EL,
+ 0xB77F19B6L, 0xE0A9DC09L, 0x662D09A1L, 0xC4324633L,
+ 0xE85A1F02L, 0x09F0BE8CL, 0x4A99A025L, 0x1D6EFE10L,
+ 0x1AB93D1DL, 0x0BA5A4DFL, 0xA186F20FL, 0x2868F169L,
+ 0xDCB7DA83L, 0x573906FEL, 0xA1E2CE9BL, 0x4FCD7F52L,
+ 0x50115E01L, 0xA70683FAL, 0xA002B5C4L, 0x0DE6D027L,
+ 0x9AF88C27L, 0x773F8641L, 0xC3604C06L, 0x61A806B5L,
+ 0xF0177A28L, 0xC0F586E0L, 0x006058AAL, 0x30DC7D62L,
+ 0x11E69ED7L, 0x2338EA63L, 0x53C2DD94L, 0xC2C21634L,
+ 0xBBCBEE56L, 0x90BCB6DEL, 0xEBFC7DA1L, 0xCE591D76L,
+ 0x6F05E409L, 0x4B7C0188L, 0x39720A3DL, 0x7C927C24L,
+ 0x86E3725FL, 0x724D9DB9L, 0x1AC15BB4L, 0xD39EB8FCL,
+ 0xED545578L, 0x08FCA5B5L, 0xD83D7CD3L, 0x4DAD0FC4L,
+ 0x1E50EF5EL, 0xB161E6F8L, 0xA28514D9L, 0x6C51133CL,
+ 0x6FD5C7E7L, 0x56E14EC4L, 0x362ABFCEL, 0xDDC6C837L,
+ 0xD79A3234L, 0x92638212L, 0x670EFA8EL, 0x406000E0L},
+
+{ 0x3A39CE37L, 0xD3FAF5CFL, 0xABC27737L, 0x5AC52D1BL,
+ 0x5CB0679EL, 0x4FA33742L, 0xD3822740L, 0x99BC9BBEL,
+ 0xD5118E9DL, 0xBF0F7315L, 0xD62D1C7EL, 0xC700C47BL,
+ 0xB78C1B6BL, 0x21A19045L, 0xB26EB1BEL, 0x6A366EB4L,
+ 0x5748AB2FL, 0xBC946E79L, 0xC6A376D2L, 0x6549C2C8L,
+ 0x530FF8EEL, 0x468DDE7DL, 0xD5730A1DL, 0x4CD04DC6L,
+ 0x2939BBDBL, 0xA9BA4650L, 0xAC9526E8L, 0xBE5EE304L,
+ 0xA1FAD5F0L, 0x6A2D519AL, 0x63EF8CE2L, 0x9A86EE22L,
+ 0xC089C2B8L, 0x43242EF6L, 0xA51E03AAL, 0x9CF2D0A4L,
+ 0x83C061BAL, 0x9BE96A4DL, 0x8FE51550L, 0xBA645BD6L,
+ 0x2826A2F9L, 0xA73A3AE1L, 0x4BA99586L, 0xEF5562E9L,
+ 0xC72FEFD3L, 0xF752F7DAL, 0x3F046F69L, 0x77FA0A59L,
+ 0x80E4A915L, 0x87B08601L, 0x9B09E6ADL, 0x3B3EE593L,
+ 0xE990FD5AL, 0x9E34D797L, 0x2CF0B7D9L, 0x022B8B51L,
+ 0x96D5AC3AL, 0x017DA67DL, 0xD1CF3ED6L, 0x7C7D2D28L,
+ 0x1F9F25CFL, 0xADF2B89BL, 0x5AD6B472L, 0x5A88F54CL,
+ 0xE029AC71L, 0xE019A5E6L, 0x47B0ACFDL, 0xED93FA9BL,
+ 0xE8D3C48DL, 0x283B57CCL, 0xF8D56629L, 0x79132E28L,
+ 0x785F0191L, 0xED756055L, 0xF7960E44L, 0xE3D35E8CL,
+ 0x15056DD4L, 0x88F46DBAL, 0x03A16125L, 0x0564F0BDL,
+ 0xC3EB9E15L, 0x3C9057A2L, 0x97271AECL, 0xA93A072AL,
+ 0x1B3F6D9BL, 0x1E6321F5L, 0xF59C66FBL, 0x26DCF319L,
+ 0x7533D928L, 0xB155FDF5L, 0x03563482L, 0x8ABA3CBBL,
+ 0x28517711L, 0xC20AD9F8L, 0xABCC5167L, 0xCCAD925FL,
+ 0x4DE81751L, 0x3830DC8EL, 0x379D5862L, 0x9320F991L,
+ 0xEA7A90C2L, 0xFB3E7BCEL, 0x5121CE64L, 0x774FBE32L,
+ 0xA8B6E37EL, 0xC3293D46L, 0x48DE5369L, 0x6413E680L,
+ 0xA2AE0810L, 0xDD6DB224L, 0x69852DFDL, 0x09072166L,
+ 0xB39A460AL, 0x6445C0DDL, 0x586CDECFL, 0x1C20C8AEL,
+ 0x5BBEF7DDL, 0x1B588D40L, 0xCCD2017FL, 0x6BB4E3BBL,
+ 0xDDA26A7EL, 0x3A59FF45L, 0x3E350A44L, 0xBCB4CDD5L,
+ 0x72EACEA8L, 0xFA6484BBL, 0x8D6612AEL, 0xBF3C6F47L,
+ 0xD29BE463L, 0x542F5D9EL, 0xAEC2771BL, 0xF64E6370L,
+ 0x740E0D8DL, 0xE75B1357L, 0xF8721671L, 0xAF537D5DL,
+ 0x4040CB08L, 0x4EB4E2CCL, 0x34D2466AL, 0x0115AF84L,
+ 0xE1B00428L, 0x95983A1DL, 0x06B89FB4L, 0xCE6EA048L,
+ 0x6F3F3B82L, 0x3520AB82L, 0x011A1D4BL, 0x277227F8L,
+ 0x611560B1L, 0xE7933FDCL, 0xBB3A792BL, 0x344525BDL,
+ 0xA08839E1L, 0x51CE794BL, 0x2F32C9B7L, 0xA01FBAC9L,
+ 0xE01CC87EL, 0xBCC7D1F6L, 0xCF0111C3L, 0xA1E8AAC7L,
+ 0x1A908749L, 0xD44FBD9AL, 0xD0DADECBL, 0xD50ADA38L,
+ 0x0339C32AL, 0xC6913667L, 0x8DF9317CL, 0xE0B12B4FL,
+ 0xF79E59B7L, 0x43F5BB3AL, 0xF2D519FFL, 0x27D9459CL,
+ 0xBF97222CL, 0x15E6FC2AL, 0x0F91FC71L, 0x9B941525L,
+ 0xFAE59361L, 0xCEB69CEBL, 0xC2A86459L, 0x12BAA8D1L,
+ 0xB6C1075EL, 0xE3056A0CL, 0x10D25065L, 0xCB03A442L,
+ 0xE0EC6E0EL, 0x1698DB3BL, 0x4C98A0BEL, 0x3278E964L,
+ 0x9F1F9532L, 0xE0D392DFL, 0xD3A0342BL, 0x8971F21EL,
+ 0x1B0A7441L, 0x4BA3348CL, 0xC5BE7120L, 0xC37632D8L,
+ 0xDF359F8DL, 0x9B992F2EL, 0xE60B6F47L, 0x0FE3F11DL,
+ 0xE54CDA54L, 0x1EDAD891L, 0xCE6279CFL, 0xCD3E7E6FL,
+ 0x1618B166L, 0xFD2C1D05L, 0x848FD2C5L, 0xF6FB2299L,
+ 0xF523F357L, 0xA6327623L, 0x93A83531L, 0x56CCCD02L,
+ 0xACF08162L, 0x5A75EBB5L, 0x6E163697L, 0x88D273CCL,
+ 0xDE966292L, 0x81B949D0L, 0x4C50901BL, 0x71C65614L,
+ 0xE6C6C7BDL, 0x327A140AL, 0x45E1D006L, 0xC3F27B9AL,
+ 0xC9AA53FDL, 0x62A80F00L, 0xBB25BFE2L, 0x35BDD2F6L,
+ 0x71126905L, 0xB2040222L, 0xB6CBCF7CL, 0xCD769C2BL,
+ 0x53113EC0L, 0x1640E3D3L, 0x38ABBD60L, 0x2547ADF0L,
+ 0xBA38209CL, 0xF746CE76L, 0x77AFA1C5L, 0x20756060L,
+ 0x85CBFE4EL, 0x8AE88DD8L, 0x7AAAF9B0L, 0x4CF9AA7EL,
+ 0x1948C25CL, 0x02FB8A8CL, 0x01C36AE4L, 0xD6EBE1F9L,
+ 0x90D4F869L, 0xA65CDEA0L, 0x3F09252DL, 0xC208E69FL,
+ 0xB74E6132L, 0xCE77E25BL, 0x578FDFE3L, 0x3AC372E6L}
+};
+//-----------------------------------------------------------------------------
+uint32_t F(BLOWFISH_CTX *ctx, uint32_t x)
+{
+unsigned short a, b, c, d;
+uint32_t y = 0;
+//uint32_t y1, y2;
+
+d = x & 0x00FF;
+x >>= 8;
+c = x & 0x00FF;
+x >>= 8;
+b = x & 0x00FF;
+x >>= 8;
+a = x & 0x00FF;
+
+/*y1 = ctx->S[0][a];
+y2 = ctx->S[1][b];
+y = y1+y2;*/
+
+y = ctx->S[0][a] + ctx->S[1][b];
+y = y ^ ctx->S[2][c];
+y = y + ctx->S[3][d];
+return y;
+}
+//-----------------------------------------------------------------------------
+void Blowfish_Encrypt(BLOWFISH_CTX *ctx, uint32_t *xl, uint32_t *xr)
+{
+uint32_t Xl;
+uint32_t Xr;
+uint32_t temp;
+short i;
+
+Xl = *xl;
+Xr = *xr;
+
+for (i = 0; i < N; ++i)
+ {
+ Xl = Xl ^ ctx->P[i];
+ Xr = F(ctx, Xl) ^ Xr;
+ temp = Xl;
+ Xl = Xr;
+ Xr = temp;
+ }
+
+temp = Xl;
+Xl = Xr;
+Xr = temp;
+Xr = Xr ^ ctx->P[N];
+Xl = Xl ^ ctx->P[N + 1];
+*xl = Xl;
+*xr = Xr;
+}
+//-----------------------------------------------------------------------------
+void Blowfish_Decrypt(BLOWFISH_CTX *ctx, uint32_t *xl, uint32_t *xr)
+{
+uint32_t Xl;
+uint32_t Xr;
+uint32_t temp;
+short i;
+
+Xl = *xl;
+Xr = *xr;
+
+for (i = N + 1; i > 1; --i)
+ {
+ Xl = Xl ^ ctx->P[i];
+ Xr = F(ctx, Xl) ^ Xr;
+ /* Exchange Xl and Xr */
+ temp = Xl;
+ Xl = Xr;
+ Xr = temp;
+ }
+
+/* Exchange Xl and Xr */
+temp = Xl;
+Xl = Xr;
+Xr = temp;
+Xr = Xr ^ ctx->P[1];
+Xl = Xl ^ ctx->P[0];
+*xl = Xl;
+*xr = Xr;
+}
+//-----------------------------------------------------------------------------
+void Blowfish_Init(BLOWFISH_CTX *ctx, unsigned char *key, int keyLen)
+{
+int i, j, k;
+uint32_t data, datal, datar;
+
+memset(ctx->S, 0, sizeof(ctx->S));
+
+for (i = 0; i < 4; i++)
+ {
+
+ for (j = 0; j < 256; j++)
+ ctx->S[i][j] = ORIG_S[i][j];
+ }
+
+j = 0;
+
+for (i = 0; i < N + 2; ++i)
+ {
+ data = 0x00000000;
+
+ for (k = 0; k < 4; ++k)
+ {
+ data = (data << 8) | key[j];
+ j = j + 1;
+ if (j >= keyLen)
+ j = 0;
+ }
+
+ ctx->P[i] = ORIG_P[i] ^ data;
+ }
+
+datal = 0x00000000;
+datar = 0x00000000;
+
+for (i = 0; i < N + 2; i += 2)
+ {
+ Blowfish_Encrypt(ctx, &datal, &datar);
+ ctx->P[i] = datal;
+ ctx->P[i + 1] = datar;
+ }
+
+for (i = 0; i < 4; ++i)
+ {
+
+ for (j = 0; j < 256; j += 2)
+ {
+ Blowfish_Encrypt(ctx, &datal, &datar);
+ ctx->S[i][j] = datal;
+ ctx->S[i][j + 1] = datar;
+ }
+ }
+}
+//-----------------------------------------------------------------------------
+void EnDecodeInit(const char * passwd, size_t length, BLOWFISH_CTX *ctx)
+{
+unsigned char keyL[PASSWD_LEN];
+
+memset(keyL, 0, PASSWD_LEN);
+
+strncpy((char *)keyL, passwd, MIN(length, PASSWD_LEN));
+
+Blowfish_Init(ctx, keyL, PASSWD_LEN);
+}
+//-----------------------------------------------------------------------------
+// Note: swap bytes order for compatibility with OpenSSL
+uint32_t bytes2block(const char * c)
+{
+ uint32_t t = (unsigned char)(*c++);
+ t += (unsigned char)(*c++) << 8;
+ t += (unsigned char)(*c++) << 16;
+ t += (unsigned char)(*c) << 24;
+ return t;
+}
+//-----------------------------------------------------------------------------
+// Note: swap bytes order for compatibility with OpenSSL
+void block2bytes(uint32_t t, char * c)
+{
+ *c++ = t & 0x000000FF;
+ *c++ = t >> 8 & 0x000000FF;
+ *c++ = t >> 16 & 0x000000FF;
+ *c = t >> 24 & 0x000000FF;
+}
+//-----------------------------------------------------------------------------
+void DecodeString(char * d, const char * s, BLOWFISH_CTX *ctx)
+{
+uint32_t a = bytes2block(s);
+uint32_t b = bytes2block(s + 4);
+
+Blowfish_Decrypt(ctx, &a, &b);
+
+block2bytes(a, d);
+block2bytes(b, d + 4);
+}
+//-----------------------------------------------------------------------------
+void EncodeString(char * d, const char * s, BLOWFISH_CTX *ctx)
+{
+uint32_t a = bytes2block(s);
+uint32_t b = bytes2block(s + 4);
+
+Blowfish_Encrypt(ctx, &a, &b);
+
+block2bytes(a, d);
+block2bytes(b, d + 4);
+}
+//-----------------------------------------------------------------------------
+++ /dev/null
-/*
- * Author : Paul Kocher
- * E-mail : pck@netcom.com
- * Date : 1997
- * Description: C implementation of the Blowfish algorithm.
- */
-
-#include <cstring>
-
-#include "blowfish.h"
-#include "stg/const.h"
-
-/*typedef struct _BCoptions
- {
- unsigned char remove;
- unsigned char standardout;
- unsigned char compression;
- unsigned char type;
- uint32_t origsize;
- unsigned char securedelete;
- } BCoptions;*/
-
-#define ENCRYPT 0
-#define DECRYPT 1
-
-#define endianBig ((unsigned char) 0x45)
-#define endianLittle ((unsigned char) 0x54)
-
-#ifdef WIN32 /* Win32 doesn't have random() or lstat */
- #define random() rand()
- #define initstate(x,y,z) srand(x)
- #define lstat(x,y) stat(x,y)
-#endif
-
-#ifndef S_ISREG
- #define S_ISREG(x) ( ((x)&S_IFMT)==S_IFREG )
-#endif
-
-
-#define N 16
-
-static uint32_t F(BLOWFISH_CTX *ctx, uint32_t x);
-static const uint32_t ORIG_P[16 + 2] = {
-0x243F6A88L, 0x85A308D3L, 0x13198A2EL, 0x03707344L,
-0xA4093822L, 0x299F31D0L, 0x082EFA98L, 0xEC4E6C89L,
-0x452821E6L, 0x38D01377L, 0xBE5466CFL, 0x34E90C6CL,
-0xC0AC29B7L, 0xC97C50DDL, 0x3F84D5B5L, 0xB5470917L,
-0x9216D5D9L, 0x8979FB1BL
-};
-
-static const uint32_t ORIG_S[4][256] = {
-{ 0xD1310BA6L, 0x98DFB5ACL, 0x2FFD72DBL, 0xD01ADFB7L,
- 0xB8E1AFEDL, 0x6A267E96L, 0xBA7C9045L, 0xF12C7F99L,
- 0x24A19947L, 0xB3916CF7L, 0x0801F2E2L, 0x858EFC16L,
- 0x636920D8L, 0x71574E69L, 0xA458FEA3L, 0xF4933D7EL,
- 0x0D95748FL, 0x728EB658L, 0x718BCD58L, 0x82154AEEL,
- 0x7B54A41DL, 0xC25A59B5L, 0x9C30D539L, 0x2AF26013L,
- 0xC5D1B023L, 0x286085F0L, 0xCA417918L, 0xB8DB38EFL,
- 0x8E79DCB0L, 0x603A180EL, 0x6C9E0E8BL, 0xB01E8A3EL,
- 0xD71577C1L, 0xBD314B27L, 0x78AF2FDAL, 0x55605C60L,
- 0xE65525F3L, 0xAA55AB94L, 0x57489862L, 0x63E81440L,
- 0x55CA396AL, 0x2AAB10B6L, 0xB4CC5C34L, 0x1141E8CEL,
- 0xA15486AFL, 0x7C72E993L, 0xB3EE1411L, 0x636FBC2AL,
- 0x2BA9C55DL, 0x741831F6L, 0xCE5C3E16L, 0x9B87931EL,
- 0xAFD6BA33L, 0x6C24CF5CL, 0x7A325381L, 0x28958677L,
- 0x3B8F4898L, 0x6B4BB9AFL, 0xC4BFE81BL, 0x66282193L,
- 0x61D809CCL, 0xFB21A991L, 0x487CAC60L, 0x5DEC8032L,
- 0xEF845D5DL, 0xE98575B1L, 0xDC262302L, 0xEB651B88L,
- 0x23893E81L, 0xD396ACC5L, 0x0F6D6FF3L, 0x83F44239L,
- 0x2E0B4482L, 0xA4842004L, 0x69C8F04AL, 0x9E1F9B5EL,
- 0x21C66842L, 0xF6E96C9AL, 0x670C9C61L, 0xABD388F0L,
- 0x6A51A0D2L, 0xD8542F68L, 0x960FA728L, 0xAB5133A3L,
- 0x6EEF0B6CL, 0x137A3BE4L, 0xBA3BF050L, 0x7EFB2A98L,
- 0xA1F1651DL, 0x39AF0176L, 0x66CA593EL, 0x82430E88L,
- 0x8CEE8619L, 0x456F9FB4L, 0x7D84A5C3L, 0x3B8B5EBEL,
- 0xE06F75D8L, 0x85C12073L, 0x401A449FL, 0x56C16AA6L,
- 0x4ED3AA62L, 0x363F7706L, 0x1BFEDF72L, 0x429B023DL,
- 0x37D0D724L, 0xD00A1248L, 0xDB0FEAD3L, 0x49F1C09BL,
- 0x075372C9L, 0x80991B7BL, 0x25D479D8L, 0xF6E8DEF7L,
- 0xE3FE501AL, 0xB6794C3BL, 0x976CE0BDL, 0x04C006BAL,
- 0xC1A94FB6L, 0x409F60C4L, 0x5E5C9EC2L, 0x196A2463L,
- 0x68FB6FAFL, 0x3E6C53B5L, 0x1339B2EBL, 0x3B52EC6FL,
- 0x6DFC511FL, 0x9B30952CL, 0xCC814544L, 0xAF5EBD09L,
- 0xBEE3D004L, 0xDE334AFDL, 0x660F2807L, 0x192E4BB3L,
- 0xC0CBA857L, 0x45C8740FL, 0xD20B5F39L, 0xB9D3FBDBL,
- 0x5579C0BDL, 0x1A60320AL, 0xD6A100C6L, 0x402C7279L,
- 0x679F25FEL, 0xFB1FA3CCL, 0x8EA5E9F8L, 0xDB3222F8L,
- 0x3C7516DFL, 0xFD616B15L, 0x2F501EC8L, 0xAD0552ABL,
- 0x323DB5FAL, 0xFD238760L, 0x53317B48L, 0x3E00DF82L,
- 0x9E5C57BBL, 0xCA6F8CA0L, 0x1A87562EL, 0xDF1769DBL,
- 0xD542A8F6L, 0x287EFFC3L, 0xAC6732C6L, 0x8C4F5573L,
- 0x695B27B0L, 0xBBCA58C8L, 0xE1FFA35DL, 0xB8F011A0L,
- 0x10FA3D98L, 0xFD2183B8L, 0x4AFCB56CL, 0x2DD1D35BL,
- 0x9A53E479L, 0xB6F84565L, 0xD28E49BCL, 0x4BFB9790L,
- 0xE1DDF2DAL, 0xA4CB7E33L, 0x62FB1341L, 0xCEE4C6E8L,
- 0xEF20CADAL, 0x36774C01L, 0xD07E9EFEL, 0x2BF11FB4L,
- 0x95DBDA4DL, 0xAE909198L, 0xEAAD8E71L, 0x6B93D5A0L,
- 0xD08ED1D0L, 0xAFC725E0L, 0x8E3C5B2FL, 0x8E7594B7L,
- 0x8FF6E2FBL, 0xF2122B64L, 0x8888B812L, 0x900DF01CL,
- 0x4FAD5EA0L, 0x688FC31CL, 0xD1CFF191L, 0xB3A8C1ADL,
- 0x2F2F2218L, 0xBE0E1777L, 0xEA752DFEL, 0x8B021FA1L,
- 0xE5A0CC0FL, 0xB56F74E8L, 0x18ACF3D6L, 0xCE89E299L,
- 0xB4A84FE0L, 0xFD13E0B7L, 0x7CC43B81L, 0xD2ADA8D9L,
- 0x165FA266L, 0x80957705L, 0x93CC7314L, 0x211A1477L,
- 0xE6AD2065L, 0x77B5FA86L, 0xC75442F5L, 0xFB9D35CFL,
- 0xEBCDAF0CL, 0x7B3E89A0L, 0xD6411BD3L, 0xAE1E7E49L,
- 0x00250E2DL, 0x2071B35EL, 0x226800BBL, 0x57B8E0AFL,
- 0x2464369BL, 0xF009B91EL, 0x5563911DL, 0x59DFA6AAL,
- 0x78C14389L, 0xD95A537FL, 0x207D5BA2L, 0x02E5B9C5L,
- 0x83260376L, 0x6295CFA9L, 0x11C81968L, 0x4E734A41L,
- 0xB3472DCAL, 0x7B14A94AL, 0x1B510052L, 0x9A532915L,
- 0xD60F573FL, 0xBC9BC6E4L, 0x2B60A476L, 0x81E67400L,
- 0x08BA6FB5L, 0x571BE91FL, 0xF296EC6BL, 0x2A0DD915L,
- 0xB6636521L, 0xE7B9F9B6L, 0xFF34052EL, 0xC5855664L,
- 0x53B02D5DL, 0xA99F8FA1L, 0x08BA4799L, 0x6E85076AL},
-
-{ 0x4B7A70E9L, 0xB5B32944L, 0xDB75092EL, 0xC4192623L,
- 0xAD6EA6B0L, 0x49A7DF7DL, 0x9CEE60B8L, 0x8FEDB266L,
- 0xECAA8C71L, 0x699A17FFL, 0x5664526CL, 0xC2B19EE1L,
- 0x193602A5L, 0x75094C29L, 0xA0591340L, 0xE4183A3EL,
- 0x3F54989AL, 0x5B429D65L, 0x6B8FE4D6L, 0x99F73FD6L,
- 0xA1D29C07L, 0xEFE830F5L, 0x4D2D38E6L, 0xF0255DC1L,
- 0x4CDD2086L, 0x8470EB26L, 0x6382E9C6L, 0x021ECC5EL,
- 0x09686B3FL, 0x3EBAEFC9L, 0x3C971814L, 0x6B6A70A1L,
- 0x687F3584L, 0x52A0E286L, 0xB79C5305L, 0xAA500737L,
- 0x3E07841CL, 0x7FDEAE5CL, 0x8E7D44ECL, 0x5716F2B8L,
- 0xB03ADA37L, 0xF0500C0DL, 0xF01C1F04L, 0x0200B3FFL,
- 0xAE0CF51AL, 0x3CB574B2L, 0x25837A58L, 0xDC0921BDL,
- 0xD19113F9L, 0x7CA92FF6L, 0x94324773L, 0x22F54701L,
- 0x3AE5E581L, 0x37C2DADCL, 0xC8B57634L, 0x9AF3DDA7L,
- 0xA9446146L, 0x0FD0030EL, 0xECC8C73EL, 0xA4751E41L,
- 0xE238CD99L, 0x3BEA0E2FL, 0x3280BBA1L, 0x183EB331L,
- 0x4E548B38L, 0x4F6DB908L, 0x6F420D03L, 0xF60A04BFL,
- 0x2CB81290L, 0x24977C79L, 0x5679B072L, 0xBCAF89AFL,
- 0xDE9A771FL, 0xD9930810L, 0xB38BAE12L, 0xDCCF3F2EL,
- 0x5512721FL, 0x2E6B7124L, 0x501ADDE6L, 0x9F84CD87L,
- 0x7A584718L, 0x7408DA17L, 0xBC9F9ABCL, 0xE94B7D8CL,
- 0xEC7AEC3AL, 0xDB851DFAL, 0x63094366L, 0xC464C3D2L,
- 0xEF1C1847L, 0x3215D908L, 0xDD433B37L, 0x24C2BA16L,
- 0x12A14D43L, 0x2A65C451L, 0x50940002L, 0x133AE4DDL,
- 0x71DFF89EL, 0x10314E55L, 0x81AC77D6L, 0x5F11199BL,
- 0x043556F1L, 0xD7A3C76BL, 0x3C11183BL, 0x5924A509L,
- 0xF28FE6EDL, 0x97F1FBFAL, 0x9EBABF2CL, 0x1E153C6EL,
- 0x86E34570L, 0xEAE96FB1L, 0x860E5E0AL, 0x5A3E2AB3L,
- 0x771FE71CL, 0x4E3D06FAL, 0x2965DCB9L, 0x99E71D0FL,
- 0x803E89D6L, 0x5266C825L, 0x2E4CC978L, 0x9C10B36AL,
- 0xC6150EBAL, 0x94E2EA78L, 0xA5FC3C53L, 0x1E0A2DF4L,
- 0xF2F74EA7L, 0x361D2B3DL, 0x1939260FL, 0x19C27960L,
- 0x5223A708L, 0xF71312B6L, 0xEBADFE6EL, 0xEAC31F66L,
- 0xE3BC4595L, 0xA67BC883L, 0xB17F37D1L, 0x018CFF28L,
- 0xC332DDEFL, 0xBE6C5AA5L, 0x65582185L, 0x68AB9802L,
- 0xEECEA50FL, 0xDB2F953BL, 0x2AEF7DADL, 0x5B6E2F84L,
- 0x1521B628L, 0x29076170L, 0xECDD4775L, 0x619F1510L,
- 0x13CCA830L, 0xEB61BD96L, 0x0334FE1EL, 0xAA0363CFL,
- 0xB5735C90L, 0x4C70A239L, 0xD59E9E0BL, 0xCBAADE14L,
- 0xEECC86BCL, 0x60622CA7L, 0x9CAB5CABL, 0xB2F3846EL,
- 0x648B1EAFL, 0x19BDF0CAL, 0xA02369B9L, 0x655ABB50L,
- 0x40685A32L, 0x3C2AB4B3L, 0x319EE9D5L, 0xC021B8F7L,
- 0x9B540B19L, 0x875FA099L, 0x95F7997EL, 0x623D7DA8L,
- 0xF837889AL, 0x97E32D77L, 0x11ED935FL, 0x16681281L,
- 0x0E358829L, 0xC7E61FD6L, 0x96DEDFA1L, 0x7858BA99L,
- 0x57F584A5L, 0x1B227263L, 0x9B83C3FFL, 0x1AC24696L,
- 0xCDB30AEBL, 0x532E3054L, 0x8FD948E4L, 0x6DBC3128L,
- 0x58EBF2EFL, 0x34C6FFEAL, 0xFE28ED61L, 0xEE7C3C73L,
- 0x5D4A14D9L, 0xE864B7E3L, 0x42105D14L, 0x203E13E0L,
- 0x45EEE2B6L, 0xA3AAABEAL, 0xDB6C4F15L, 0xFACB4FD0L,
- 0xC742F442L, 0xEF6ABBB5L, 0x654F3B1DL, 0x41CD2105L,
- 0xD81E799EL, 0x86854DC7L, 0xE44B476AL, 0x3D816250L,
- 0xCF62A1F2L, 0x5B8D2646L, 0xFC8883A0L, 0xC1C7B6A3L,
- 0x7F1524C3L, 0x69CB7492L, 0x47848A0BL, 0x5692B285L,
- 0x095BBF00L, 0xAD19489DL, 0x1462B174L, 0x23820E00L,
- 0x58428D2AL, 0x0C55F5EAL, 0x1DADF43EL, 0x233F7061L,
- 0x3372F092L, 0x8D937E41L, 0xD65FECF1L, 0x6C223BDBL,
- 0x7CDE3759L, 0xCBEE7460L, 0x4085F2A7L, 0xCE77326EL,
- 0xA6078084L, 0x19F8509EL, 0xE8EFD855L, 0x61D99735L,
- 0xA969A7AAL, 0xC50C06C2L, 0x5A04ABFCL, 0x800BCADCL,
- 0x9E447A2EL, 0xC3453484L, 0xFDD56705L, 0x0E1E9EC9L,
- 0xDB73DBD3L, 0x105588CDL, 0x675FDA79L, 0xE3674340L,
- 0xC5C43465L, 0x713E38D8L, 0x3D28F89EL, 0xF16DFF20L,
- 0x153E21E7L, 0x8FB03D4AL, 0xE6E39F2BL, 0xDB83ADF7L},
-
-{ 0xE93D5A68L, 0x948140F7L, 0xF64C261CL, 0x94692934L,
- 0x411520F7L, 0x7602D4F7L, 0xBCF46B2EL, 0xD4A20068L,
- 0xD4082471L, 0x3320F46AL, 0x43B7D4B7L, 0x500061AFL,
- 0x1E39F62EL, 0x97244546L, 0x14214F74L, 0xBF8B8840L,
- 0x4D95FC1DL, 0x96B591AFL, 0x70F4DDD3L, 0x66A02F45L,
- 0xBFBC09ECL, 0x03BD9785L, 0x7FAC6DD0L, 0x31CB8504L,
- 0x96EB27B3L, 0x55FD3941L, 0xDA2547E6L, 0xABCA0A9AL,
- 0x28507825L, 0x530429F4L, 0x0A2C86DAL, 0xE9B66DFBL,
- 0x68DC1462L, 0xD7486900L, 0x680EC0A4L, 0x27A18DEEL,
- 0x4F3FFEA2L, 0xE887AD8CL, 0xB58CE006L, 0x7AF4D6B6L,
- 0xAACE1E7CL, 0xD3375FECL, 0xCE78A399L, 0x406B2A42L,
- 0x20FE9E35L, 0xD9F385B9L, 0xEE39D7ABL, 0x3B124E8BL,
- 0x1DC9FAF7L, 0x4B6D1856L, 0x26A36631L, 0xEAE397B2L,
- 0x3A6EFA74L, 0xDD5B4332L, 0x6841E7F7L, 0xCA7820FBL,
- 0xFB0AF54EL, 0xD8FEB397L, 0x454056ACL, 0xBA489527L,
- 0x55533A3AL, 0x20838D87L, 0xFE6BA9B7L, 0xD096954BL,
- 0x55A867BCL, 0xA1159A58L, 0xCCA92963L, 0x99E1DB33L,
- 0xA62A4A56L, 0x3F3125F9L, 0x5EF47E1CL, 0x9029317CL,
- 0xFDF8E802L, 0x04272F70L, 0x80BB155CL, 0x05282CE3L,
- 0x95C11548L, 0xE4C66D22L, 0x48C1133FL, 0xC70F86DCL,
- 0x07F9C9EEL, 0x41041F0FL, 0x404779A4L, 0x5D886E17L,
- 0x325F51EBL, 0xD59BC0D1L, 0xF2BCC18FL, 0x41113564L,
- 0x257B7834L, 0x602A9C60L, 0xDFF8E8A3L, 0x1F636C1BL,
- 0x0E12B4C2L, 0x02E1329EL, 0xAF664FD1L, 0xCAD18115L,
- 0x6B2395E0L, 0x333E92E1L, 0x3B240B62L, 0xEEBEB922L,
- 0x85B2A20EL, 0xE6BA0D99L, 0xDE720C8CL, 0x2DA2F728L,
- 0xD0127845L, 0x95B794FDL, 0x647D0862L, 0xE7CCF5F0L,
- 0x5449A36FL, 0x877D48FAL, 0xC39DFD27L, 0xF33E8D1EL,
- 0x0A476341L, 0x992EFF74L, 0x3A6F6EABL, 0xF4F8FD37L,
- 0xA812DC60L, 0xA1EBDDF8L, 0x991BE14CL, 0xDB6E6B0DL,
- 0xC67B5510L, 0x6D672C37L, 0x2765D43BL, 0xDCD0E804L,
- 0xF1290DC7L, 0xCC00FFA3L, 0xB5390F92L, 0x690FED0BL,
- 0x667B9FFBL, 0xCEDB7D9CL, 0xA091CF0BL, 0xD9155EA3L,
- 0xBB132F88L, 0x515BAD24L, 0x7B9479BFL, 0x763BD6EBL,
- 0x37392EB3L, 0xCC115979L, 0x8026E297L, 0xF42E312DL,
- 0x6842ADA7L, 0xC66A2B3BL, 0x12754CCCL, 0x782EF11CL,
- 0x6A124237L, 0xB79251E7L, 0x06A1BBE6L, 0x4BFB6350L,
- 0x1A6B1018L, 0x11CAEDFAL, 0x3D25BDD8L, 0xE2E1C3C9L,
- 0x44421659L, 0x0A121386L, 0xD90CEC6EL, 0xD5ABEA2AL,
- 0x64AF674EL, 0xDA86A85FL, 0xBEBFE988L, 0x64E4C3FEL,
- 0x9DBC8057L, 0xF0F7C086L, 0x60787BF8L, 0x6003604DL,
- 0xD1FD8346L, 0xF6381FB0L, 0x7745AE04L, 0xD736FCCCL,
- 0x83426B33L, 0xF01EAB71L, 0xB0804187L, 0x3C005E5FL,
- 0x77A057BEL, 0xBDE8AE24L, 0x55464299L, 0xBF582E61L,
- 0x4E58F48FL, 0xF2DDFDA2L, 0xF474EF38L, 0x8789BDC2L,
- 0x5366F9C3L, 0xC8B38E74L, 0xB475F255L, 0x46FCD9B9L,
- 0x7AEB2661L, 0x8B1DDF84L, 0x846A0E79L, 0x915F95E2L,
- 0x466E598EL, 0x20B45770L, 0x8CD55591L, 0xC902DE4CL,
- 0xB90BACE1L, 0xBB8205D0L, 0x11A86248L, 0x7574A99EL,
- 0xB77F19B6L, 0xE0A9DC09L, 0x662D09A1L, 0xC4324633L,
- 0xE85A1F02L, 0x09F0BE8CL, 0x4A99A025L, 0x1D6EFE10L,
- 0x1AB93D1DL, 0x0BA5A4DFL, 0xA186F20FL, 0x2868F169L,
- 0xDCB7DA83L, 0x573906FEL, 0xA1E2CE9BL, 0x4FCD7F52L,
- 0x50115E01L, 0xA70683FAL, 0xA002B5C4L, 0x0DE6D027L,
- 0x9AF88C27L, 0x773F8641L, 0xC3604C06L, 0x61A806B5L,
- 0xF0177A28L, 0xC0F586E0L, 0x006058AAL, 0x30DC7D62L,
- 0x11E69ED7L, 0x2338EA63L, 0x53C2DD94L, 0xC2C21634L,
- 0xBBCBEE56L, 0x90BCB6DEL, 0xEBFC7DA1L, 0xCE591D76L,
- 0x6F05E409L, 0x4B7C0188L, 0x39720A3DL, 0x7C927C24L,
- 0x86E3725FL, 0x724D9DB9L, 0x1AC15BB4L, 0xD39EB8FCL,
- 0xED545578L, 0x08FCA5B5L, 0xD83D7CD3L, 0x4DAD0FC4L,
- 0x1E50EF5EL, 0xB161E6F8L, 0xA28514D9L, 0x6C51133CL,
- 0x6FD5C7E7L, 0x56E14EC4L, 0x362ABFCEL, 0xDDC6C837L,
- 0xD79A3234L, 0x92638212L, 0x670EFA8EL, 0x406000E0L},
-
-{ 0x3A39CE37L, 0xD3FAF5CFL, 0xABC27737L, 0x5AC52D1BL,
- 0x5CB0679EL, 0x4FA33742L, 0xD3822740L, 0x99BC9BBEL,
- 0xD5118E9DL, 0xBF0F7315L, 0xD62D1C7EL, 0xC700C47BL,
- 0xB78C1B6BL, 0x21A19045L, 0xB26EB1BEL, 0x6A366EB4L,
- 0x5748AB2FL, 0xBC946E79L, 0xC6A376D2L, 0x6549C2C8L,
- 0x530FF8EEL, 0x468DDE7DL, 0xD5730A1DL, 0x4CD04DC6L,
- 0x2939BBDBL, 0xA9BA4650L, 0xAC9526E8L, 0xBE5EE304L,
- 0xA1FAD5F0L, 0x6A2D519AL, 0x63EF8CE2L, 0x9A86EE22L,
- 0xC089C2B8L, 0x43242EF6L, 0xA51E03AAL, 0x9CF2D0A4L,
- 0x83C061BAL, 0x9BE96A4DL, 0x8FE51550L, 0xBA645BD6L,
- 0x2826A2F9L, 0xA73A3AE1L, 0x4BA99586L, 0xEF5562E9L,
- 0xC72FEFD3L, 0xF752F7DAL, 0x3F046F69L, 0x77FA0A59L,
- 0x80E4A915L, 0x87B08601L, 0x9B09E6ADL, 0x3B3EE593L,
- 0xE990FD5AL, 0x9E34D797L, 0x2CF0B7D9L, 0x022B8B51L,
- 0x96D5AC3AL, 0x017DA67DL, 0xD1CF3ED6L, 0x7C7D2D28L,
- 0x1F9F25CFL, 0xADF2B89BL, 0x5AD6B472L, 0x5A88F54CL,
- 0xE029AC71L, 0xE019A5E6L, 0x47B0ACFDL, 0xED93FA9BL,
- 0xE8D3C48DL, 0x283B57CCL, 0xF8D56629L, 0x79132E28L,
- 0x785F0191L, 0xED756055L, 0xF7960E44L, 0xE3D35E8CL,
- 0x15056DD4L, 0x88F46DBAL, 0x03A16125L, 0x0564F0BDL,
- 0xC3EB9E15L, 0x3C9057A2L, 0x97271AECL, 0xA93A072AL,
- 0x1B3F6D9BL, 0x1E6321F5L, 0xF59C66FBL, 0x26DCF319L,
- 0x7533D928L, 0xB155FDF5L, 0x03563482L, 0x8ABA3CBBL,
- 0x28517711L, 0xC20AD9F8L, 0xABCC5167L, 0xCCAD925FL,
- 0x4DE81751L, 0x3830DC8EL, 0x379D5862L, 0x9320F991L,
- 0xEA7A90C2L, 0xFB3E7BCEL, 0x5121CE64L, 0x774FBE32L,
- 0xA8B6E37EL, 0xC3293D46L, 0x48DE5369L, 0x6413E680L,
- 0xA2AE0810L, 0xDD6DB224L, 0x69852DFDL, 0x09072166L,
- 0xB39A460AL, 0x6445C0DDL, 0x586CDECFL, 0x1C20C8AEL,
- 0x5BBEF7DDL, 0x1B588D40L, 0xCCD2017FL, 0x6BB4E3BBL,
- 0xDDA26A7EL, 0x3A59FF45L, 0x3E350A44L, 0xBCB4CDD5L,
- 0x72EACEA8L, 0xFA6484BBL, 0x8D6612AEL, 0xBF3C6F47L,
- 0xD29BE463L, 0x542F5D9EL, 0xAEC2771BL, 0xF64E6370L,
- 0x740E0D8DL, 0xE75B1357L, 0xF8721671L, 0xAF537D5DL,
- 0x4040CB08L, 0x4EB4E2CCL, 0x34D2466AL, 0x0115AF84L,
- 0xE1B00428L, 0x95983A1DL, 0x06B89FB4L, 0xCE6EA048L,
- 0x6F3F3B82L, 0x3520AB82L, 0x011A1D4BL, 0x277227F8L,
- 0x611560B1L, 0xE7933FDCL, 0xBB3A792BL, 0x344525BDL,
- 0xA08839E1L, 0x51CE794BL, 0x2F32C9B7L, 0xA01FBAC9L,
- 0xE01CC87EL, 0xBCC7D1F6L, 0xCF0111C3L, 0xA1E8AAC7L,
- 0x1A908749L, 0xD44FBD9AL, 0xD0DADECBL, 0xD50ADA38L,
- 0x0339C32AL, 0xC6913667L, 0x8DF9317CL, 0xE0B12B4FL,
- 0xF79E59B7L, 0x43F5BB3AL, 0xF2D519FFL, 0x27D9459CL,
- 0xBF97222CL, 0x15E6FC2AL, 0x0F91FC71L, 0x9B941525L,
- 0xFAE59361L, 0xCEB69CEBL, 0xC2A86459L, 0x12BAA8D1L,
- 0xB6C1075EL, 0xE3056A0CL, 0x10D25065L, 0xCB03A442L,
- 0xE0EC6E0EL, 0x1698DB3BL, 0x4C98A0BEL, 0x3278E964L,
- 0x9F1F9532L, 0xE0D392DFL, 0xD3A0342BL, 0x8971F21EL,
- 0x1B0A7441L, 0x4BA3348CL, 0xC5BE7120L, 0xC37632D8L,
- 0xDF359F8DL, 0x9B992F2EL, 0xE60B6F47L, 0x0FE3F11DL,
- 0xE54CDA54L, 0x1EDAD891L, 0xCE6279CFL, 0xCD3E7E6FL,
- 0x1618B166L, 0xFD2C1D05L, 0x848FD2C5L, 0xF6FB2299L,
- 0xF523F357L, 0xA6327623L, 0x93A83531L, 0x56CCCD02L,
- 0xACF08162L, 0x5A75EBB5L, 0x6E163697L, 0x88D273CCL,
- 0xDE966292L, 0x81B949D0L, 0x4C50901BL, 0x71C65614L,
- 0xE6C6C7BDL, 0x327A140AL, 0x45E1D006L, 0xC3F27B9AL,
- 0xC9AA53FDL, 0x62A80F00L, 0xBB25BFE2L, 0x35BDD2F6L,
- 0x71126905L, 0xB2040222L, 0xB6CBCF7CL, 0xCD769C2BL,
- 0x53113EC0L, 0x1640E3D3L, 0x38ABBD60L, 0x2547ADF0L,
- 0xBA38209CL, 0xF746CE76L, 0x77AFA1C5L, 0x20756060L,
- 0x85CBFE4EL, 0x8AE88DD8L, 0x7AAAF9B0L, 0x4CF9AA7EL,
- 0x1948C25CL, 0x02FB8A8CL, 0x01C36AE4L, 0xD6EBE1F9L,
- 0x90D4F869L, 0xA65CDEA0L, 0x3F09252DL, 0xC208E69FL,
- 0xB74E6132L, 0xCE77E25BL, 0x578FDFE3L, 0x3AC372E6L}
-};
-//-----------------------------------------------------------------------------
-uint32_t F(BLOWFISH_CTX *ctx, uint32_t x)
-{
-unsigned short a, b, c, d;
-uint32_t y = 0;
-//uint32_t y1, y2;
-
-d = x & 0x00FF;
-x >>= 8;
-c = x & 0x00FF;
-x >>= 8;
-b = x & 0x00FF;
-x >>= 8;
-a = x & 0x00FF;
-
-/*y1 = ctx->S[0][a];
-y2 = ctx->S[1][b];
-y = y1+y2;*/
-
-y = ctx->S[0][a] + ctx->S[1][b];
-y = y ^ ctx->S[2][c];
-y = y + ctx->S[3][d];
-return y;
-}
-//-----------------------------------------------------------------------------
-void Blowfish_Encrypt(BLOWFISH_CTX *ctx, uint32_t *xl, uint32_t *xr)
-{
-uint32_t Xl;
-uint32_t Xr;
-uint32_t temp;
-short i;
-
-Xl = *xl;
-Xr = *xr;
-
-for (i = 0; i < N; ++i)
- {
- Xl = Xl ^ ctx->P[i];
- Xr = F(ctx, Xl) ^ Xr;
- temp = Xl;
- Xl = Xr;
- Xr = temp;
- }
-
-temp = Xl;
-Xl = Xr;
-Xr = temp;
-Xr = Xr ^ ctx->P[N];
-Xl = Xl ^ ctx->P[N + 1];
-*xl = Xl;
-*xr = Xr;
-}
-//-----------------------------------------------------------------------------
-void Blowfish_Decrypt(BLOWFISH_CTX *ctx, uint32_t *xl, uint32_t *xr)
-{
-uint32_t Xl;
-uint32_t Xr;
-uint32_t temp;
-short i;
-
-Xl = *xl;
-Xr = *xr;
-
-for (i = N + 1; i > 1; --i)
- {
- Xl = Xl ^ ctx->P[i];
- Xr = F(ctx, Xl) ^ Xr;
- /* Exchange Xl and Xr */
- temp = Xl;
- Xl = Xr;
- Xr = temp;
- }
-
-/* Exchange Xl and Xr */
-temp = Xl;
-Xl = Xr;
-Xr = temp;
-Xr = Xr ^ ctx->P[1];
-Xl = Xl ^ ctx->P[0];
-*xl = Xl;
-*xr = Xr;
-}
-//-----------------------------------------------------------------------------
-void Blowfish_Init(BLOWFISH_CTX *ctx, unsigned char *key, int keyLen)
-{
-int i, j, k;
-uint32_t data, datal, datar;
-
-memset(ctx->S, 0, sizeof(ctx->S));
-
-for (i = 0; i < 4; i++)
- {
-
- for (j = 0; j < 256; j++)
- ctx->S[i][j] = ORIG_S[i][j];
- }
-
-j = 0;
-
-for (i = 0; i < N + 2; ++i)
- {
- data = 0x00000000;
-
- for (k = 0; k < 4; ++k)
- {
- data = (data << 8) | key[j];
- j = j + 1;
- if (j >= keyLen)
- j = 0;
- }
-
- ctx->P[i] = ORIG_P[i] ^ data;
- }
-
-datal = 0x00000000;
-datar = 0x00000000;
-
-for (i = 0; i < N + 2; i += 2)
- {
- Blowfish_Encrypt(ctx, &datal, &datar);
- ctx->P[i] = datal;
- ctx->P[i + 1] = datar;
- }
-
-for (i = 0; i < 4; ++i)
- {
-
- for (j = 0; j < 256; j += 2)
- {
- Blowfish_Encrypt(ctx, &datal, &datar);
- ctx->S[i][j] = datal;
- ctx->S[i][j + 1] = datar;
- }
- }
-}
-//-----------------------------------------------------------------------------
-void EnDecodeInit(const char * passwd, int, BLOWFISH_CTX *ctx)
-{
-unsigned char * keyL = NULL;//[PASSWD_LEN]; // ðÁÒÏÌØ ÄÌÑ ÛÉÆÒÏ×ËÉ
-
-keyL = new unsigned char[PASSWD_LEN];
-
-memset(keyL, 0, PASSWD_LEN);
-
-strncpy((char *)keyL, passwd, PASSWD_LEN);
-
-Blowfish_Init(ctx, keyL, PASSWD_LEN);
-
-delete[] keyL;
-}
-//-----------------------------------------------------------------------------
-// Note: swap bytes order for compatibility with OpenSSL
-uint32_t bytes2block(const char * c)
-{
- uint32_t t = static_cast<unsigned char>(*c++);
- t += static_cast<unsigned char>(*c++) << 8;
- t += static_cast<unsigned char>(*c++) << 16;
- t += static_cast<unsigned char>(*c) << 24;
- return t;
-}
-//-----------------------------------------------------------------------------
-// Note: swap bytes order for compatibility with OpenSSL
-void block2bytes(uint32_t t, char * c)
-{
- *c++ = t & 0x000000FF;
- *c++ = t >> 8 & 0x000000FF;
- *c++ = t >> 16 & 0x000000FF;
- *c = t >> 24 & 0x000000FF;
-}
-//-----------------------------------------------------------------------------
-void DecodeString(char * d, const char * s, BLOWFISH_CTX *ctx)
-{
-uint32_t a = bytes2block(s);
-uint32_t b = bytes2block(s + 4);
-
-Blowfish_Decrypt(ctx, &a, &b);
-
-block2bytes(a, d);
-block2bytes(b, d + 4);
-}
-//-----------------------------------------------------------------------------
-void EncodeString(char * d, const char * s, BLOWFISH_CTX *ctx)
-{
-uint32_t a = bytes2block(s);
-uint32_t b = bytes2block(s + 4);
-
-Blowfish_Encrypt(ctx, &a, &b);
-
-block2bytes(a, d);
-block2bytes(b, d + 4);
-}
-//-----------------------------------------------------------------------------
+++ /dev/null
-/*
- * Author : Paul Kocher
- * E-mail : pck@netcom.com
- * Date : 1997
- * Description: C implementation of the Blowfish algorithm.
- */
-
-#ifndef BLOWFISH_H
-#define BLOWFISH_H
-
-#include "stg/os_int.h"
-
-#define MAXKEYBYTES 56 /* 448 bits */
-
-typedef struct {
- uint32_t P[16 + 2];
- uint32_t S[4][256];
-} BLOWFISH_CTX;
-
-void Blowfish_Init(BLOWFISH_CTX *ctx, unsigned char *key, int keyLen);
-void Blowfish_Encrypt(BLOWFISH_CTX *ctx, uint32_t *xl, uint32_t *xr);
-void Blowfish_Decrypt(BLOWFISH_CTX *ctx, uint32_t *xl, uint32_t *xr);
-
-void EnDecodeInit(const char * key, int passwdLen, BLOWFISH_CTX *ctx);
-void DecodeString(char * d, const char * s, BLOWFISH_CTX *ctx);
-void EncodeString(char * d, const char * s, BLOWFISH_CTX *ctx);
-
-#endif
-
--- /dev/null
+#ifndef _MD5_H
+#define _MD5_H
+
+#include <time.h>
+
+#include "stg/os_int.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct MD5Context {
+ uint32_t buf[4];
+ uint32_t bits[2];
+ unsigned char in[64];
+};
+
+typedef struct MD5Context MD5_CTX;
+
+char *crypt_make_salt(void);
+void byteReverse(unsigned char*, unsigned);
+void MD5Init(struct MD5Context *ctx);
+void MD5Update(struct MD5Context*, char const*, unsigned);
+void MD5Final(unsigned char digest[16], struct MD5Context *ctx);
+void MD5Transform(uint32_t buf[4], uint32_t const in[16]);
+char *libshadow_md5_crypt(const char*, const char*);
+char *pw_encrypt(const char*, const char*);
+
+/* AG functions */
+char *make_ag_hash(time_t salt, const char *clear);
+int check_ag_hash(time_t salt, const char *clear, const char *hash);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null
+/*
+ * Author : Paul Kocher
+ * E-mail : pck@netcom.com
+ * Date : 1997
+ * Description: C implementation of the Blowfish algorithm.
+ */
+
+#ifndef BLOWFISH_H
+#define BLOWFISH_H
+
+#include "stg/os_int.h"
+
+#define MAXKEYBYTES 56 /* 448 bits */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+ uint32_t P[16 + 2];
+ uint32_t S[4][256];
+} BLOWFISH_CTX;
+
+void Blowfish_Init(BLOWFISH_CTX *ctx, unsigned char *key, int keyLen);
+void Blowfish_Encrypt(BLOWFISH_CTX *ctx, uint32_t *xl, uint32_t *xr);
+void Blowfish_Decrypt(BLOWFISH_CTX *ctx, uint32_t *xl, uint32_t *xr);
+
+void EnDecodeInit(const char * key, size_t length, BLOWFISH_CTX *ctx);
+void DecodeString(char * d, const char * s, BLOWFISH_CTX *ctx);
+void EncodeString(char * d, const char * s, BLOWFISH_CTX *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
# $Id: Makefile,v 1.3 2007/05/08 14:29:19 faust Exp $
###############################################################################
-LIB_NAME = dotconfpp
+LIB_NAME = stgdotconfpp
SRCS = dotconfpp.cpp \
mempool.cpp
#include <glob.h> // glob
#include <string>
-#include "dotconfpp.h"
+#include "stg/dotconfpp.h"
#include "mempool.h"
DOTCONFDocumentNode::DOTCONFDocumentNode():previousNode(NULL), nextNode(NULL), parentNode(NULL), childNode(NULL),
+++ /dev/null
-/* Copyright (C) 2003 Aleksey Krivoshey <voodoo@foss.kharkov.ua>
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; if not, write to the Free Software
-* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-
-#ifndef DOTCONFPP_H
-#define DOTCONFPP_H
-
-#include <list>
-
-#include <stdarg.h>
-#include <stdio.h>
-#include <string.h>
-#include <strings.h>
-#include <ctype.h>
-#include <errno.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <limits.h>
-
-#include "stg/os_int.h"
-
-typedef void (* DOTCONFCallback) (void * data, const char * buf);
-
-class DOTCONFDocument;
-class AsyncDNSMemPool;
-
-class DOTCONFDocumentNode
-{
-friend class DOTCONFDocument;
-private:
- DOTCONFDocumentNode * previousNode;
- DOTCONFDocumentNode * nextNode;
- DOTCONFDocumentNode * parentNode;
- DOTCONFDocumentNode * childNode;
- char ** values;
- int valuesCount;
- char * name;
- const DOTCONFDocument * document;
- int lineNum;
- char * fileName;
- bool closed;
-
- void pushValue(char * _value);
-
-public:
- DOTCONFDocumentNode();
- ~DOTCONFDocumentNode();
-
- const char * getConfigurationFileName() const { return fileName; }
- int getConfigurationLineNumber() const { return lineNum; }
-
- const DOTCONFDocumentNode * getNextNode() const { return nextNode; }
- const DOTCONFDocumentNode * getPreviuosNode() const { return previousNode; }
- const DOTCONFDocumentNode * getParentNode() const { return parentNode; }
- const DOTCONFDocumentNode * getChildNode() const { return childNode; }
- const char * getValue(int index = 0) const;
- const char * getName() const { return name; }
- const DOTCONFDocument * getDocument() const { return document; }
-};
-
-class DOTCONFDocument
-{
-public:
- enum CaseSensitive { CASESENSITIVE, CASEINSENSITIVE };
-protected:
- AsyncDNSMemPool * mempool;
-private:
- DOTCONFDocumentNode * curParent;
- DOTCONFDocumentNode * curPrev;
- DOTCONFCallback errorCallback;
- void * errorCallbackData;
- int curLine;
- bool quoted;
- std::list<DOTCONFDocumentNode *> nodeTree;
- std::list<char *> requiredOptions;
- std::list<char *> processedFiles;
- FILE * file;
- char * fileName;
- std::list<char *> words;
- int (* cmp_func)(const char *, const char *);
-
- int checkRequiredOptions();
- int parseLine();
- int parseFile(DOTCONFDocumentNode * _parent = NULL);
- int checkConfig(const std::list<DOTCONFDocumentNode *>::iterator & from);
- int cleanupLine(char * line);
- char * getSubstitution(char * macro, int lineNum);
- int macroSubstitute(DOTCONFDocumentNode * tagNode, int valueIndex);
-
-protected:
- virtual void error(int lineNum, const char * fileName, const char * fmt, ...);
-
-public:
- DOTCONFDocument(CaseSensitive caseSensitivity = CASESENSITIVE);
- virtual ~DOTCONFDocument();
-
- void setErrorCallback(DOTCONFCallback _callback, void * _data) { errorCallback = _callback; errorCallbackData = _data; };
-
- int setContent(const char * _fileName);
-
- void setRequiredOptionNames(const char ** requiredOptionNames); // !TERMINATE ARRAY WITH NULL
- const DOTCONFDocumentNode * getFirstNode() const;
- const DOTCONFDocumentNode * findNode(const char * nodeName, const DOTCONFDocumentNode * parentNode = NULL, const DOTCONFDocumentNode * startNode = NULL) const;
-};
-
-#endif
--- /dev/null
+/* Copyright (C) 2003 Aleksey Krivoshey <voodoo@foss.kharkov.ua>
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef DOTCONFPP_H
+#define DOTCONFPP_H
+
+#include <list>
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+#include <ctype.h>
+#include <errno.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <limits.h>
+
+#include "stg/os_int.h"
+
+typedef void (* DOTCONFCallback) (void * data, const char * buf);
+
+class DOTCONFDocument;
+class AsyncDNSMemPool;
+
+class DOTCONFDocumentNode
+{
+friend class DOTCONFDocument;
+private:
+ DOTCONFDocumentNode * previousNode;
+ DOTCONFDocumentNode * nextNode;
+ DOTCONFDocumentNode * parentNode;
+ DOTCONFDocumentNode * childNode;
+ char ** values;
+ int valuesCount;
+ char * name;
+ const DOTCONFDocument * document;
+ int lineNum;
+ char * fileName;
+ bool closed;
+
+ void pushValue(char * _value);
+
+public:
+ DOTCONFDocumentNode();
+ ~DOTCONFDocumentNode();
+
+ const char * getConfigurationFileName() const { return fileName; }
+ int getConfigurationLineNumber() const { return lineNum; }
+
+ const DOTCONFDocumentNode * getNextNode() const { return nextNode; }
+ const DOTCONFDocumentNode * getPreviuosNode() const { return previousNode; }
+ const DOTCONFDocumentNode * getParentNode() const { return parentNode; }
+ const DOTCONFDocumentNode * getChildNode() const { return childNode; }
+ const char * getValue(int index = 0) const;
+ const char * getName() const { return name; }
+ const DOTCONFDocument * getDocument() const { return document; }
+};
+
+class DOTCONFDocument
+{
+public:
+ enum CaseSensitive { CASESENSITIVE, CASEINSENSITIVE };
+protected:
+ AsyncDNSMemPool * mempool;
+private:
+ DOTCONFDocumentNode * curParent;
+ DOTCONFDocumentNode * curPrev;
+ DOTCONFCallback errorCallback;
+ void * errorCallbackData;
+ int curLine;
+ bool quoted;
+ std::list<DOTCONFDocumentNode *> nodeTree;
+ std::list<char *> requiredOptions;
+ std::list<char *> processedFiles;
+ FILE * file;
+ char * fileName;
+ std::list<char *> words;
+ int (* cmp_func)(const char *, const char *);
+
+ int checkRequiredOptions();
+ int parseLine();
+ int parseFile(DOTCONFDocumentNode * _parent = NULL);
+ int checkConfig(const std::list<DOTCONFDocumentNode *>::iterator & from);
+ int cleanupLine(char * line);
+ char * getSubstitution(char * macro, int lineNum);
+ int macroSubstitute(DOTCONFDocumentNode * tagNode, int valueIndex);
+
+protected:
+ virtual void error(int lineNum, const char * fileName, const char * fmt, ...);
+
+public:
+ DOTCONFDocument(CaseSensitive caseSensitivity = CASESENSITIVE);
+ virtual ~DOTCONFDocument();
+
+ void setErrorCallback(DOTCONFCallback _callback, void * _data) { errorCallback = _callback; errorCallbackData = _data; };
+
+ int setContent(const char * _fileName);
+
+ void setRequiredOptionNames(const char ** requiredOptionNames); // !TERMINATE ARRAY WITH NULL
+ const DOTCONFDocumentNode * getFirstNode() const;
+ const DOTCONFDocumentNode * findNode(const char * nodeName, const DOTCONFDocumentNode * parentNode = NULL, const DOTCONFDocumentNode * startNode = NULL) const;
+};
+
+#endif
INCS = ia.h
-STGLIBS = -lstgcommon \
- -lstgcrypto
+STGLIBS = -lstgcrypto
+
LIBS = $(LIB_THREAD)
+LIB_INCS = -I ../crypto.lib/include \
+ -I ../common.lib/include
+
include ../Makefile.in
//---------------------------------------------------------------------------
+#ifdef WIN32
+#include <winsock2.h>
+#include <windows.h>
+#include <winbase.h>
+#include <winnt.h>
+#else
+#include <fcntl.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+#include <csignal>
+#endif
+
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cassert>
-#ifdef WIN32
- #include <winsock2.h>
- #include <windows.h>
- #include <winbase.h>
- #include <winnt.h>
-#else
- #include <fcntl.h>
- #include <netdb.h>
- #include <arpa/inet.h>
- #include <unistd.h>
-#endif
-
#include "stg/common.h"
-#include "ia.h"
+#include "stg/ia.h"
#define IA_NONE (0)
#define IA_CONNECT (1)
//---------------------------------------------------------------------------
#ifndef WIN32
#include <sys/time.h>
+void Sleep(int ms)
+{
+long long res = ms * 1000000;
+struct timespec ts = {res / 1000000000, res % 1000000000};
+nanosleep(&ts, NULL);
+}
+//---------------------------------------------------------------------------
void * RunL(void * data)
{
+sigset_t signalSet;
+sigfillset(&signalSet);
+pthread_sigmask(SIG_BLOCK, &signalSet, NULL);
IA_CLIENT_PROT * c = (IA_CLIENT_PROT *)data;
static int a = 0;
if (a == 0)
{
- usleep(50000);
+ Sleep(50);
a = 1;
}
return NULL;
}
//---------------------------------------------------------------------------
-void Sleep(int ms)
-{
-usleep(ms * 1000);
-}
-//---------------------------------------------------------------------------
long GetTickCount()
{
struct timeval tv;
+++ /dev/null
-/*
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 1, or (at your option)
-** any later version.
-
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-/*
- $Author: faust $
- $Revision: 1.10 $
- $Date: 2010/03/15 12:57:24 $
-*/
-
-/*
-* Author : Boris Mikhailenko <stg34@stargazer.dp.ua>
-*/
-//---------------------------------------------------------------------------
-#ifndef IA_AUTH_C_H
-#define IA_AUTH_C_H
-
-#ifndef WIN32
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <pthread.h>
-#else
-#include <winsock2.h>
-#endif
-
-#include <string>
-#include <vector>
-#include <map>
-
-#include "stg/blowfish.h"
-#include "stg/ia_packets.h"
-
-#define IA_BIND_ERROR (1)
-#define IA_SERVER_ERROR (2)
-#define IA_FCNTL_ERROR (3)
-#define IA_GETHOSTBYNAME_ERROR (4)
-
-#define IA_PROTO_VER (8)
-#define IA_PROTO_PROXY_VER (101)
-
-using namespace std;
-
-typedef void (*tpStatusChangedCb)(int status, void * data);
-typedef void (*tpStatChangedCb)(const LOADSTAT & stat, void * data);
-typedef void (*tpCallBackInfoFn)(const string & message, int infoType, int showTime, int sendTime, void * data);
-typedef void (*tpCallBackErrorFn)(const string & message, int netError, void * data);
-typedef void (*tpCallBackDirNameFn)(const vector<string> & dirName, void * data);
-
-//---------------------------------------------------------------------------
-class IA_CLIENT_PROT
-{
-#ifdef WIN32
-friend unsigned long WINAPI RunW(void * data);
-#else
-friend void * RunL(void * data);
-#endif
-
-public:
- IA_CLIENT_PROT(const string & sn, uint16_t p, uint16_t localPort = 0);
- ~IA_CLIENT_PROT();
-
- void Start();
- void Stop();
- void GetStat(LOADSTAT * ls);
-
- void SetServer(const string & sn, unsigned short port);
- void SetLogin(const string & login);
- void SetPassword(const string & password);
- void SetEnabledDirs(const bool * selectedDirs);
-
- void SetStatusChangedCb(tpStatusChangedCb p, void * data);
- void SetStatChangedCb(tpStatChangedCb p, void * data);
- void SetInfoCb(tpCallBackInfoFn p, void * data);
- void SetErrorCb(tpCallBackErrorFn p, void * data);
- void SetDirNameCb(tpCallBackDirNameFn p, void * data);
-
- int Connect();
- int Disconnect();
- int GetAuthorized() const { return phase == 3 || phase == 4; };
- int GetPhase() const { return phase; };
- int GetStatus() const;
- int GetReconnect() const { return reconnect; };
- void SetReconnect(int r) { reconnect = r; };
- char GetProtoVer() const { return proxyMode ? IA_PROTO_PROXY_VER : IA_PROTO_VER; };
- void GetMessageText(string * text) const { *text = messageText; };
- void GetInfoText(string * text) const { *text = infoText; };
- int GetStrError(string * error) const;
-
- void SetProxyMode(bool on) { proxyMode = on; };
- bool GetProxyMode() const { return proxyMode; };
-
- void SetIP(uint32_t ip) { IA_CLIENT_PROT::ip = ip; };
- uint32_t GetIP() const { return ip; };
-
-private:
- void Run();
- int NetRecv();
- int NetSend(int n);
- bool GetNonstop() const { return nonstop; };
- void PrepareNet();
- int DeterminatePacketType(const char * buffer);
-
- int Process_CONN_SYN_ACK_8(const char * buffer);
- int Process_ALIVE_SYN_8(const char * buffer);
- int Process_DISCONN_SYN_ACK_8(const char * buffer);
- int Process_FIN_8(const char * buffer);
- int Process_INFO_8(const char * buffer);
- int Process_ERROR(const char * buffer);
-
- int Prepare_CONN_SYN_8(char * buffer);
- int Prepare_CONN_ACK_8(char * buffer);
- int Prepare_ALIVE_ACK_8(char * buffer);
- int Prepare_DISCONN_SYN_8(char * buffer);
- int Prepare_DISCONN_ACK_8(char * buffer);
-
- void FillHdr8(char * buffer, unsigned long ip);
- int Send(char * buffer, int len);
- int Recv(char * buffer, int len);
-
- LOADSTAT stat;
- int action;
- int phase;
- int phaseTime;
- string messageText;
- string infoText;
- mutable string strError;
- mutable int codeError;
- bool nonstop;
- bool isNetPrepared;
- bool proxyMode;
-
- BLOWFISH_CTX ctxPass;
- BLOWFISH_CTX ctxHdr;
-
- bool selectedDirs[DIR_NUM];
-
- string password;
- string login;
-
- #ifdef WIN32
- WSADATA wsaData;
- #else
- pthread_t thread;
- #endif
-
- string serverName;
- uint16_t port;
- uint32_t ip;
- uint32_t localPort;
-
- struct sockaddr_in servAddr;
-
- bool firstConnect;
- int reconnect;
- int sockr;
- int protNum;
- int userTimeout;
- int aliveTimeout;
- unsigned int rnd;
-
- tpStatusChangedCb pStatusChangedCb;
- tpStatChangedCb pStatChangedCb;
- tpCallBackInfoFn pInfoCb;
- tpCallBackErrorFn pErrorCb;
- tpCallBackDirNameFn pDirNameCb;
-
- void * statusChangedCbData;
- void * statChangedCbData;
- void * infoCbData;
- void * errorCbData;
- void * dirNameCbData;
-
- map<string, int> packetTypes;
-
- CONN_SYN_8 * connSyn8;
- CONN_SYN_ACK_8 * connSynAck8;
- CONN_ACK_8 * connAck8;
- ALIVE_SYN_8 * aliveSyn8;
- ALIVE_ACK_8 * aliveAck8;
- DISCONN_SYN_8 * disconnSyn8;
- DISCONN_SYN_ACK_8 * disconnSynAck8;
- DISCONN_ACK_8 * disconnAck8;
- INFO_8 * info;
-};
-//---------------------------------------------------------------------------
-#ifdef WIN32
-unsigned long WINAPI RunW(void *);
-#else
-void * RunW(void *);
-#endif
-
-//---------------------------------------------------------------------------
-#endif //IA_AUTH_C_H
--- /dev/null
+/*
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 1, or (at your option)
+** any later version.
+
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+ $Author: faust $
+ $Revision: 1.10 $
+ $Date: 2010/03/15 12:57:24 $
+*/
+
+/*
+* Author : Boris Mikhailenko <stg34@stargazer.dp.ua>
+*/
+//---------------------------------------------------------------------------
+#ifndef IA_AUTH_C_H
+#define IA_AUTH_C_H
+
+#ifndef WIN32
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <pthread.h>
+#else
+#include <winsock2.h>
+#endif
+
+#include <string>
+#include <vector>
+#include <map>
+
+#include "stg/blowfish.h"
+#include "stg/ia_packets.h"
+
+#define IA_BIND_ERROR (1)
+#define IA_SERVER_ERROR (2)
+#define IA_FCNTL_ERROR (3)
+#define IA_GETHOSTBYNAME_ERROR (4)
+
+#define IA_PROTO_VER (8)
+#define IA_PROTO_PROXY_VER (101)
+
+using namespace std;
+
+typedef void (*tpStatusChangedCb)(int status, void * data);
+typedef void (*tpStatChangedCb)(const LOADSTAT & stat, void * data);
+typedef void (*tpCallBackInfoFn)(const string & message, int infoType, int showTime, int sendTime, void * data);
+typedef void (*tpCallBackErrorFn)(const string & message, int netError, void * data);
+typedef void (*tpCallBackDirNameFn)(const vector<string> & dirName, void * data);
+
+//---------------------------------------------------------------------------
+class IA_CLIENT_PROT
+{
+#ifdef WIN32
+friend unsigned long WINAPI RunW(void * data);
+#else
+friend void * RunL(void * data);
+#endif
+
+public:
+ IA_CLIENT_PROT(const string & sn, uint16_t p, uint16_t localPort = 0);
+ ~IA_CLIENT_PROT();
+
+ void Start();
+ void Stop();
+ void GetStat(LOADSTAT * ls);
+
+ void SetServer(const string & sn, unsigned short port);
+ void SetLogin(const string & login);
+ void SetPassword(const string & password);
+ void SetEnabledDirs(const bool * selectedDirs);
+
+ void SetStatusChangedCb(tpStatusChangedCb p, void * data);
+ void SetStatChangedCb(tpStatChangedCb p, void * data);
+ void SetInfoCb(tpCallBackInfoFn p, void * data);
+ void SetErrorCb(tpCallBackErrorFn p, void * data);
+ void SetDirNameCb(tpCallBackDirNameFn p, void * data);
+
+ int Connect();
+ int Disconnect();
+ int GetAuthorized() const { return phase == 3 || phase == 4; };
+ int GetPhase() const { return phase; };
+ int GetStatus() const;
+ int GetReconnect() const { return reconnect; };
+ void SetReconnect(int r) { reconnect = r; };
+ char GetProtoVer() const { return proxyMode ? IA_PROTO_PROXY_VER : IA_PROTO_VER; };
+ void GetMessageText(string * text) const { *text = messageText; };
+ void GetInfoText(string * text) const { *text = infoText; };
+ int GetStrError(string * error) const;
+
+ void SetProxyMode(bool on) { proxyMode = on; };
+ bool GetProxyMode() const { return proxyMode; };
+
+ void SetIP(uint32_t ip) { IA_CLIENT_PROT::ip = ip; };
+ uint32_t GetIP() const { return ip; };
+
+private:
+ void Run();
+ int NetRecv();
+ int NetSend(int n);
+ bool GetNonstop() const { return nonstop; };
+ void PrepareNet();
+ int DeterminatePacketType(const char * buffer);
+
+ int Process_CONN_SYN_ACK_8(const char * buffer);
+ int Process_ALIVE_SYN_8(const char * buffer);
+ int Process_DISCONN_SYN_ACK_8(const char * buffer);
+ int Process_FIN_8(const char * buffer);
+ int Process_INFO_8(const char * buffer);
+ int Process_ERROR(const char * buffer);
+
+ int Prepare_CONN_SYN_8(char * buffer);
+ int Prepare_CONN_ACK_8(char * buffer);
+ int Prepare_ALIVE_ACK_8(char * buffer);
+ int Prepare_DISCONN_SYN_8(char * buffer);
+ int Prepare_DISCONN_ACK_8(char * buffer);
+
+ void FillHdr8(char * buffer, unsigned long ip);
+ int Send(char * buffer, int len);
+ int Recv(char * buffer, int len);
+
+ LOADSTAT stat;
+ int action;
+ int phase;
+ int phaseTime;
+ string messageText;
+ string infoText;
+ mutable string strError;
+ mutable int codeError;
+ bool nonstop;
+ bool isNetPrepared;
+ bool proxyMode;
+
+ BLOWFISH_CTX ctxPass;
+ BLOWFISH_CTX ctxHdr;
+
+ bool selectedDirs[DIR_NUM];
+
+ string password;
+ string login;
+
+ #ifdef WIN32
+ WSADATA wsaData;
+ #else
+ pthread_t thread;
+ #endif
+
+ string serverName;
+ uint16_t port;
+ uint32_t ip;
+ uint32_t localPort;
+
+ struct sockaddr_in servAddr;
+
+ bool firstConnect;
+ int reconnect;
+ int sockr;
+ int protNum;
+ int userTimeout;
+ int aliveTimeout;
+ unsigned int rnd;
+
+ tpStatusChangedCb pStatusChangedCb;
+ tpStatChangedCb pStatChangedCb;
+ tpCallBackInfoFn pInfoCb;
+ tpCallBackErrorFn pErrorCb;
+ tpCallBackDirNameFn pDirNameCb;
+
+ void * statusChangedCbData;
+ void * statChangedCbData;
+ void * infoCbData;
+ void * errorCbData;
+ void * dirNameCbData;
+
+ map<string, int> packetTypes;
+
+ CONN_SYN_8 * connSyn8;
+ CONN_SYN_ACK_8 * connSynAck8;
+ CONN_ACK_8 * connAck8;
+ ALIVE_SYN_8 * aliveSyn8;
+ ALIVE_ACK_8 * aliveAck8;
+ DISCONN_SYN_8 * disconnSyn8;
+ DISCONN_SYN_ACK_8 * disconnSynAck8;
+ DISCONN_ACK_8 * disconnAck8;
+ INFO_8 * info;
+};
+//---------------------------------------------------------------------------
+#ifdef WIN32
+unsigned long WINAPI RunW(void *);
+#else
+void * RunW(void *);
+#endif
+
+//---------------------------------------------------------------------------
+#endif //IA_AUTH_C_H
# $Id: Makefile,v 1.6 2009/03/03 15:50:15 faust Exp $
###############################################################################
-LIB_NAME = ibpp
+LIB_NAME = stgibpp
SRCS = array.cpp \
blob.cpp \
INCS = ibpp.h
-ADD_DEFS = -DIBPP_LINUX
+LIB_DEFS = -DIBPP_LINUX
LIBS = -lfbclient
#ifndef __INTERNAL_IBPP_H__\r
#define __INTERNAL_IBPP_H__\r
\r
-#include "ibpp.h"\r
+#include "stg/ibpp.h"\r
\r
#if defined(__BCPLUSPLUS__) || defined(_MSC_VER) || defined(__DMC__)\r
#define HAS_HDRSTOP\r
+++ /dev/null
-///////////////////////////////////////////////////////////////////////////////\r
-//\r
-// File : $Id: ibpp.h,v 1.3 2007/10/28 11:17:44 nobunaga Exp $\r
-// Subject : IBPP public header file. This is _the_ only file you include in\r
-// your application files when developing with IBPP.\r
-//\r
-///////////////////////////////////////////////////////////////////////////////\r
-//\r
-// (C) Copyright 2000-2006 T.I.P. Group S.A. and the IBPP Team (www.ibpp.org)\r
-//\r
-// The contents of this file are subject to the IBPP License (the "License");\r
-// you may not use this file except in compliance with the License. You may\r
-// obtain a copy of the License at http://www.ibpp.org or in the 'license.txt'\r
-// file which must have been distributed along with this file.\r
-//\r
-// This software, distributed under the License, is distributed on an "AS IS"\r
-// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the\r
-// License for the specific language governing rights and limitations\r
-// under the License.\r
-//\r
-// Contributor(s):\r
-//\r
-// Olivier Mascia, main coding\r
-// Matt Hortman, initial linux port\r
-// Mark Jordan, design contributions\r
-// Maxim Abrashkin, enhancement patches\r
-// Torsten Martinsen, enhancement patches\r
-// Michael Hieke, darwin (OS X) port, enhancement patches\r
-// Val Samko, enhancement patches and debugging\r
-// Mike Nordell, invaluable C++ advices\r
-// Claudio Valderrama, help with not-so-well documented IB/FB features\r
-// Many others, excellent suggestions, bug finding, and support\r
-//\r
-///////////////////////////////////////////////////////////////////////////////\r
-//\r
-// COMMENTS\r
-// Tabulations should be set every four characters when editing this file.\r
-//\r
-// When compiling a project using IBPP, the following defines should be made\r
-// on the command-line (or in makefiles) according to the OS platform and\r
-// compiler used.\r
-//\r
-// Select the platform: IBPP_WINDOWS | IBPP_LINUX | IBPP_DARWIN\r
-//\r
-///////////////////////////////////////////////////////////////////////////////\r
-\r
-#ifndef __IBPP_H__\r
-#define __IBPP_H__\r
-\r
-#if !defined(IBPP_WINDOWS) && !defined(IBPP_LINUX) && !defined(IBPP_DARWIN)\r
-#error Please define IBPP_WINDOWS/IBPP_LINUX/IBPP_DARWIN before compiling !\r
-#endif\r
-\r
-#if !defined(__BCPLUSPLUS__) && !defined(__GNUC__) && !defined(_MSC_VER) && !defined(__DMC__)
-#error Your compiler is not recognized.\r
-#endif\r
-\r
-#if defined(IBPP_LINUX) || defined(IBPP_DARWIN)\r
-#define IBPP_UNIX // IBPP_UNIX stands as a common denominator to *NIX flavours\r
-#endif\r
-\r
-// IBPP is written for 32 bits systems or higher.\r
-// The standard type 'int' is assumed to be at least 32 bits.\r
-// And the standard type 'short' is assumed to be exactly 16 bits.\r
-// Everywhere possible, where the exact size of an integer does not matter,\r
-// the standard type 'int' is used. And where an exact integer size is required\r
-// the standard exact precision types definitions of C 99 standard are used.\r
-\r
-#if defined(_MSC_VER) || defined(__DMC__) || defined(__BCPLUSPLUS__)\r
-// C99 §7.18.1.1 Exact-width integer types (only those used by IBPP)\r
-#if defined(_MSC_VER) && (_MSC_VER < 1300) // MSVC 6 should be < 1300\r
- typedef short int16_t;\r
- typedef int int32_t;\r
- typedef unsigned int uint32_t;\r
-#else\r
- typedef __int16 int16_t;\r
- typedef __int32 int32_t;\r
- typedef unsigned __int32 uint32_t;\r
-#endif\r
- typedef __int64 int64_t;\r
-#else\r
- #include <stg/os_int.h> // C99 (§7.18) integer types definitions\r
-#endif\r
-\r
-#if !defined(_)\r
-#define _(s) s\r
-#endif\r
-\r
-#include <exception>\r
-#include <string>\r
-#include <vector>\r
-\r
-namespace IBPP\r
-{\r
- // Typically you use this constant in a call IBPP::CheckVersion as in:\r
- // if (! IBPP::CheckVersion(IBPP::Version)) { throw .... ; }\r
- const uint32_t Version = (2<<24) + (5<<16) + (3<<8) + 0; // Version == 2.5.3.0\r
-\r
- // Dates range checking\r
- const int MinDate = -693594; // 1 JAN 0001\r
- const int MaxDate = 2958464; // 31 DEC 9999\r
- \r
- // Transaction Access Modes\r
- enum TAM {amWrite, amRead};\r
-\r
- // Transaction Isolation Levels\r
- enum TIL {ilConcurrency, ilReadDirty, ilReadCommitted, ilConsistency};\r
-\r
- // Transaction Lock Resolution\r
- enum TLR {lrWait, lrNoWait};\r
-\r
- // Transaction Table Reservation\r
- enum TTR {trSharedWrite, trSharedRead, trProtectedWrite, trProtectedRead};\r
-\r
- // Prepared Statement Types\r
- enum STT {stUnknown, stUnsupported,\r
- stSelect, stInsert, stUpdate, stDelete, stDDL, stExecProcedure,\r
- stSelectUpdate, stSetGenerator, stSavePoint};\r
-\r
- // SQL Data Types\r
- enum SDT {sdArray, sdBlob, sdDate, sdTime, sdTimestamp, sdString,\r
- sdSmallint, sdInteger, sdLargeint, sdFloat, sdDouble};\r
-\r
- // Array Data Types\r
- enum ADT {adDate, adTime, adTimestamp, adString,\r
- adBool, adInt16, adInt32, adInt64, adFloat, adDouble};\r
-\r
- // Database::Shutdown Modes\r
- enum DSM {dsForce, dsDenyTrans, dsDenyAttach};\r
-\r
- // Service::StartBackup && Service::StartRestore Flags\r
- enum BRF {\r
- brVerbose = 0x1,\r
- // Backup flags\r
- brIgnoreChecksums = 0x100, brIgnoreLimbo = 0x200,\r
- brMetadataOnly = 0x400, brNoGarbageCollect = 0x800,\r
- brNonTransportable = 0x1000, brConvertExtTables = 0x2000,\r
- // Restore flags\r
- brReplace = 0x10000, brDeactivateIdx = 0x20000,\r
- brNoShadow = 0x40000, brNoValidity = 0x80000,\r
- brPerTableCommit = 0x100000, brUseAllSpace = 0x200000\r
- };\r
-\r
- // Service::Repair Flags\r
- enum RPF\r
- {\r
- // Mandatory and mutually exclusives\r
- rpMendRecords = 0x1, rpValidatePages = 0x2, rpValidateFull = 0x4,\r
- // Options\r
- rpReadOnly = 0x100, rpIgnoreChecksums = 0x200, rpKillShadows = 0x400\r
- };\r
-\r
- // TransactionFactory Flags\r
- enum TFF {tfIgnoreLimbo = 0x1, tfAutoCommit = 0x2, tfNoAutoUndo = 0x4};\r
-\r
- /* IBPP never return any error codes. It throws exceptions.\r
- * On database engine reported errors, an IBPP::SQLException is thrown.\r
- * In all other cases, IBPP throws IBPP::LogicException.\r
- * Also note that the runtime and the language might also throw exceptions\r
- * while executing some IBPP methods. A failing new operator will throw\r
- * std::bad_alloc, IBPP does nothing to alter the standard behaviour.\r
- *\r
- * std::exception\r
- * |\r
- * IBPP::Exception\r
- * / \\r
- * IBPP::LogicException IBPP::SQLException\r
- * |\r
- * IBPP::WrongType\r
- */\r
-\r
- class Exception : public std::exception\r
- {\r
- public:\r
- virtual const char* Origin() const throw() = 0;\r
- virtual const char* ErrorMessage() const throw() = 0; // Deprecated, use what()\r
- virtual const char* what() const throw() = 0;\r
- virtual ~Exception() throw();\r
- };\r
-\r
- class LogicException : public Exception\r
- {\r
- public:\r
- virtual ~LogicException() throw();\r
- };\r
-\r
- class SQLException : public Exception\r
- {\r
- public:\r
- virtual int SqlCode() const throw() = 0;\r
- virtual int EngineCode() const throw() = 0;\r
- \r
- virtual ~SQLException() throw();\r
- };\r
-\r
- class WrongType : public LogicException\r
- {\r
- public:\r
- virtual ~WrongType() throw();\r
- };\r
- \r
- /* Classes Date, Time, Timestamp and DBKey are 'helper' classes. They help\r
- * in retrieving or setting some special SQL types. Dates, times and dbkeys\r
- * are often read and written as strings in SQL scripts. When programming\r
- * with IBPP, we handle those data with these specific classes, which\r
- * enhance their usefullness and free us of format problems (M/D/Y, D/M/Y,\r
- * Y-M-D ?, and so on...). */\r
-\r
- /* Class Date represent purely a Date (no time part specified). It is\r
- * usefull in interactions with the SQL DATE type of Interbase. You can add\r
- * or substract a number from a Date, that will modify it to represent the\r
- * correct date, X days later or sooner. All the Y2K details taken into\r
- * account.\r
- * The full range goes from integer values IBPP::MinDate to IBPP::MaxDate\r
- * which means from 01 Jan 0001 to 31 Dec 9999. ( Which is inherently\r
- * incorrect as this assumes Gregorian calendar. ) */\r
- \r
- class Timestamp; // Cross-reference between Timestamp, Date and Time\r
- \r
- class Date\r
- {\r
- protected:\r
- int mDate; // The date : 1 == 1 Jan 1900\r
-\r
- public:\r
- void Clear() { mDate = MinDate - 1; };\r
- void Today();\r
- void SetDate(int year, int month, int day);\r
- void SetDate(int dt);\r
- void GetDate(int& year, int& month, int& day) const;\r
- int GetDate() const { return mDate; }\r
- int Year() const;\r
- int Month() const;\r
- int Day() const;\r
- void Add(int days);\r
- void StartOfMonth();\r
- void EndOfMonth();\r
- \r
- Date() { Clear(); };\r
- Date(int dt) { SetDate(dt); }\r
- Date(int year, int month, int day);\r
- Date(const Date&); // Copy Constructor\r
- Date& operator=(const Timestamp&); // Timestamp Assignment operator\r
- Date& operator=(const Date&); // Date Assignment operator\r
-\r
- bool operator==(const Date& rv) const { return mDate == rv.GetDate(); }\r
- bool operator!=(const Date& rv) const { return mDate != rv.GetDate(); }\r
- bool operator<(const Date& rv) const { return mDate < rv.GetDate(); }\r
- bool operator>(const Date& rv) const { return mDate > rv.GetDate(); }\r
-\r
- virtual ~Date() { };\r
- };\r
-\r
- /* Class Time represent purely a Time. It is usefull in interactions\r
- * with the SQL TIME type of Interbase. */\r
-\r
- class Time\r
- {\r
- protected:\r
- int mTime; // The time, in ten-thousandths of seconds since midnight\r
-\r
- public:\r
- void Clear() { mTime = 0; }\r
- void Now();\r
- void SetTime(int hour, int minute, int second, int tenthousandths = 0);\r
- void SetTime(int tm);\r
- void GetTime(int& hour, int& minute, int& second) const;\r
- void GetTime(int& hour, int& minute, int& second, int& tenthousandths) const;\r
- int GetTime() const { return mTime; }\r
- int Hours() const;\r
- int Minutes() const;\r
- int Seconds() const;\r
- int SubSeconds() const; // Actually tenthousandths of seconds\r
- Time() { Clear(); }\r
- Time(int tm) { SetTime(tm); }\r
- Time(int hour, int minute, int second, int tenthousandths = 0);\r
- Time(const Time&); // Copy Constructor\r
- Time& operator=(const Timestamp&); // Timestamp Assignment operator\r
- Time& operator=(const Time&); // Time Assignment operator\r
-\r
- bool operator==(const Time& rv) const { return mTime == rv.GetTime(); }\r
- bool operator!=(const Time& rv) const { return mTime != rv.GetTime(); }\r
- bool operator<(const Time& rv) const { return mTime < rv.GetTime(); }\r
- bool operator>(const Time& rv) const { return mTime > rv.GetTime(); }\r
-\r
- virtual ~Time() { };\r
- };\r
-\r
- /* Class Timestamp represent a date AND a time. It is usefull in\r
- * interactions with the SQL TIMESTAMP type of Interbase. This class\r
- * inherits from Date and Time and completely inline implements its small\r
- * specific details. */\r
-\r
- class Timestamp : public Date, public Time\r
- {\r
- public:\r
- void Clear() { Date::Clear(); Time::Clear(); }\r
- void Today() { Date::Today(); Time::Clear(); }\r
- void Now() { Date::Today(); Time::Now(); }\r
-\r
- Timestamp() { Clear(); }\r
-\r
- Timestamp(int y, int m, int d)\r
- { Date::SetDate(y, m, d); Time::Clear(); }\r
-\r
- Timestamp(int y, int mo, int d, int h, int mi, int s, int t = 0)\r
- { Date::SetDate(y, mo, d); Time::SetTime(h, mi, s, t); }\r
-\r
- Timestamp(const Timestamp& rv)\r
- : Date(rv.mDate), Time(rv.mTime) {} // Copy Constructor\r
-\r
- Timestamp(const Date& rv)\r
- { mDate = rv.GetDate(); mTime = 0; }\r
-\r
- Timestamp(const Time& rv)\r
- { mDate = 0; mTime = rv.GetTime(); }\r
-\r
- Timestamp& operator=(const Timestamp& rv) // Timestamp Assignment operator\r
- { mDate = rv.mDate; mTime = rv.mTime; return *this; }\r
-\r
- Timestamp& operator=(const Date& rv) // Date Assignment operator\r
- { mDate = rv.GetDate(); return *this; }\r
-\r
- Timestamp& operator=(const Time& rv) // Time Assignment operator\r
- { mTime = rv.GetTime(); return *this; }\r
-\r
- bool operator==(const Timestamp& rv) const\r
- { return (mDate == rv.GetDate()) && (mTime == rv.GetTime()); }\r
-\r
- bool operator!=(const Timestamp& rv) const\r
- { return (mDate != rv.GetDate()) || (mTime != rv.GetTime()); }\r
-\r
- bool operator<(const Timestamp& rv) const\r
- { return (mDate < rv.GetDate()) ||\r
- (mDate == rv.GetDate() && mTime < rv.GetTime()); }\r
-\r
- bool operator>(const Timestamp& rv) const\r
- { return (mDate > rv.GetDate()) ||\r
- (mDate == rv.GetDate() && mTime > rv.GetTime()); }\r
-\r
- ~Timestamp() { }\r
- };\r
-\r
- /* Class DBKey can store a DBKEY, that special value which the hidden\r
- * RDB$DBKEY can give you from a select statement. A DBKey is nothing\r
- * specific to IBPP. It's a feature of the Firebird database engine. See its\r
- * documentation for more information. */\r
-\r
- class DBKey\r
- {\r
- private:\r
- std::string mDBKey; // Stores the binary DBKey\r
- mutable std::string mString;// String (temporary) representation of it\r
-\r
- public:\r
- void Clear();\r
- int Size() const { return (int)mDBKey.size(); }\r
- void SetKey(const void*, int size);\r
- void GetKey(void*, int size) const;\r
- const char* AsString() const;\r
-\r
- DBKey& operator=(const DBKey&); // Assignment operator\r
- DBKey(const DBKey&); // Copy Constructor\r
- DBKey() { }\r
- ~DBKey() { }\r
- };\r
-\r
- /* Class User wraps all the information about a user that the engine can manage. */\r
-\r
- class User\r
- {\r
- public:\r
- std::string username;\r
- std::string password;\r
- std::string firstname;\r
- std::string middlename;\r
- std::string lastname;\r
- uint32_t userid; // Only relevant on unixes\r
- uint32_t groupid; // Only relevant on unixes\r
-\r
- private:\r
- void copyfrom(const User& r);\r
-\r
- public:\r
- void clear();\r
- User& operator=(const User& r) { copyfrom(r); return *this; }\r
- User(const User& r) { copyfrom(r); }\r
- User() : userid(0), groupid(0) { }\r
- ~User() { };\r
- };\r
-\r
- // Interface Wrapper\r
- template <class T>\r
- class Ptr\r
- {\r
- private:\r
- T* mObject;\r
-\r
- public:\r
- void clear()\r
- {\r
- if (mObject != 0) { mObject->Release(); mObject = 0; }\r
- }\r
-\r
- T* intf() const { return mObject; }\r
- T* operator->() const { return mObject; }\r
-\r
- bool operator==(const T* p) const { return mObject == p; }\r
- bool operator==(const Ptr& r) const { return mObject == r.mObject; }\r
- bool operator!=(const T* p) const { return mObject != p; }\r
- bool operator!=(const Ptr& r) const { return mObject != r.mObject; }\r
-\r
- Ptr& operator=(T* p)\r
- {\r
- // AddRef _before_ Release gives correct behaviour on self-assigns\r
- T* tmp = (p == 0 ? 0 : p->AddRef()); // Take care of 0\r
- if (mObject != 0) mObject->Release();\r
- mObject = tmp; return *this;\r
- }\r
-\r
- Ptr& operator=(const Ptr& r)\r
- {\r
- // AddRef _before_ Release gives correct behaviour on self-assigns\r
- T* tmp = (r.intf() == 0 ? 0 : r->AddRef());// Take care of 0\r
- if (mObject != 0) mObject->Release();\r
- mObject = tmp; return *this;\r
- }\r
-\r
- Ptr(T* p) : mObject(p == 0 ? 0 : p->AddRef()) { }\r
- Ptr(const Ptr& r) : mObject(r.intf() == 0 ? 0 : r->AddRef()) { }\r
-\r
- Ptr() : mObject(0) { }\r
- ~Ptr() { clear(); }\r
- };\r
-\r
- // --- Interface Classes --- //\r
-\r
- /* Interfaces IBlob, IArray, IService, IDatabase, ITransaction and\r
- * IStatement are at the core of IBPP. Though it is possible to program your\r
- * applications by using theses interfaces directly (as was the case with\r
- * IBPP 1.x), you should refrain from using them and prefer the new IBPP\r
- * Objects Blob, Array, ... (without the I in front). Those new objects are\r
- * typedef'd right after each interface class definition as you can read\r
- * below. If you program using the Blob (instead of the IBlob interface\r
- * itself), you'll never have to care about AddRef/Release and you'll never\r
- * have to care about deleting your objects. */\r
-\r
- class IBlob; typedef Ptr<IBlob> Blob;\r
- class IArray; typedef Ptr<IArray> Array;\r
- class IService; typedef Ptr<IService> Service;\r
- class IDatabase; typedef Ptr<IDatabase> Database;\r
- class ITransaction; typedef Ptr<ITransaction> Transaction;\r
- class IStatement; typedef Ptr<IStatement> Statement;\r
- class IEvents; typedef Ptr<IEvents> Events;\r
- class IRow; typedef Ptr<IRow> Row;\r
-\r
- /* IBlob is the interface to the blob capabilities of IBPP. Blob is the\r
- * object class you actually use in your programming. In Firebird, at the\r
- * row level, a blob is merely a handle to a blob, stored elsewhere in the\r
- * database. Blob allows you to retrieve such a handle and then read from or\r
- * write to the blob, much in the same manner than you would do with a file. */\r
-\r
- class IBlob\r
- {\r
- public:\r
- virtual void Create() = 0;\r
- virtual void Open() = 0;\r
- virtual void Close() = 0;\r
- virtual void Cancel() = 0;\r
- virtual int Read(void*, int size) = 0;\r
- virtual void Write(const void*, int size) = 0;\r
- virtual void Info(int* Size, int* Largest, int* Segments) = 0;\r
- \r
- virtual void Save(const std::string& data) = 0;\r
- virtual void Load(std::string& data) = 0;\r
-\r
- virtual Database DatabasePtr() const = 0;\r
- virtual Transaction TransactionPtr() const = 0;\r
-\r
- virtual IBlob* AddRef() = 0;\r
- virtual void Release() = 0;\r
-\r
- virtual ~IBlob() { };\r
- };\r
-\r
- /* IArray is the interface to the array capabilities of IBPP. Array is the\r
- * object class you actually use in your programming. With an Array object, you\r
- * can create, read and write Interbase Arrays, as a whole or in slices. */\r
-\r
- class IArray\r
- {\r
- public:\r
- virtual void Describe(const std::string& table, const std::string& column) = 0;\r
- virtual void ReadTo(ADT, void* buffer, int elemcount) = 0;\r
- virtual void WriteFrom(ADT, const void* buffer, int elemcount) = 0;\r
- virtual SDT ElementType() = 0;\r
- virtual int ElementSize() = 0;\r
- virtual int ElementScale() = 0;\r
- virtual int Dimensions() = 0;\r
- virtual void Bounds(int dim, int* low, int* high) = 0;\r
- virtual void SetBounds(int dim, int low, int high) = 0;\r
-\r
- virtual Database DatabasePtr() const = 0;\r
- virtual Transaction TransactionPtr() const = 0;\r
-\r
- virtual IArray* AddRef() = 0;\r
- virtual void Release() = 0;\r
-\r
- virtual ~IArray() { };\r
- };\r
-\r
- /* IService is the interface to the service capabilities of IBPP. Service is\r
- * the object class you actually use in your programming. With a Service\r
- * object, you can do some maintenance work of databases and servers\r
- * (backup, restore, create/update users, ...) */\r
-\r
- class IService\r
- {\r
- public:\r
- virtual void Connect() = 0;\r
- virtual bool Connected() = 0;\r
- virtual void Disconnect() = 0;\r
-\r
- virtual void GetVersion(std::string& version) = 0;\r
-\r
- virtual void AddUser(const User&) = 0;\r
- virtual void GetUser(User&) = 0;\r
- virtual void GetUsers(std::vector<User>&) = 0;\r
- virtual void ModifyUser(const User&) = 0;\r
- virtual void RemoveUser(const std::string& username) = 0;\r
-\r
- virtual void SetPageBuffers(const std::string& dbfile, int buffers) = 0;\r
- virtual void SetSweepInterval(const std::string& dbfile, int sweep) = 0;\r
- virtual void SetSyncWrite(const std::string& dbfile, bool) = 0;\r
- virtual void SetReadOnly(const std::string& dbfile, bool) = 0;\r
- virtual void SetReserveSpace(const std::string& dbfile, bool) = 0;\r
-\r
- virtual void Shutdown(const std::string& dbfile, DSM mode, int sectimeout) = 0;\r
- virtual void Restart(const std::string& dbfile) = 0;\r
- virtual void Sweep(const std::string& dbfile) = 0;\r
- virtual void Repair(const std::string& dbfile, RPF flags) = 0;\r
-\r
- virtual void StartBackup(const std::string& dbfile,\r
- const std::string& bkfile, BRF flags = BRF(0)) = 0;\r
- virtual void StartRestore(const std::string& bkfile, const std::string& dbfile,\r
- int pagesize = 0, BRF flags = BRF(0)) = 0;\r
-\r
- virtual const char* WaitMsg() = 0; // With reporting (does not block)\r
- virtual void Wait() = 0; // Without reporting (does block)\r
-\r
- virtual IService* AddRef() = 0;\r
- virtual void Release() = 0;\r
-\r
- virtual ~IService() { };\r
- };\r
-\r
- /* IDatabase is the interface to the database connections in IBPP. Database\r
- * is the object class you actually use in your programming. With a Database\r
- * object, you can create/drop/connect databases. */\r
-\r
- class EventInterface; // Cross-reference between EventInterface and IDatabase\r
- \r
- class IDatabase\r
- {\r
- public:\r
- virtual const char* ServerName() const = 0;\r
- virtual const char* DatabaseName() const = 0;\r
- virtual const char* Username() const = 0;\r
- virtual const char* UserPassword() const = 0;\r
- virtual const char* RoleName() const = 0;\r
- virtual const char* CharSet() const = 0;\r
- virtual const char* CreateParams() const = 0;\r
-\r
- virtual void Info(int* ODS, int* ODSMinor, int* PageSize,\r
- int* Pages, int* Buffers, int* Sweep, bool* Sync,\r
- bool* Reserve) = 0;\r
- virtual void Statistics(int* Fetches, int* Marks,\r
- int* Reads, int* Writes) = 0;\r
- virtual void Counts(int* Insert, int* Update, int* Delete, \r
- int* ReadIdx, int* ReadSeq) = 0;\r
- virtual void Users(std::vector<std::string>& users) = 0;\r
- virtual int Dialect() = 0;\r
-\r
- virtual void Create(int dialect) = 0;\r
- virtual void Connect() = 0;\r
- virtual bool Connected() = 0;\r
- virtual void Inactivate() = 0;\r
- virtual void Disconnect() = 0;\r
- virtual void Drop() = 0;\r
-\r
- virtual IDatabase* AddRef() = 0;\r
- virtual void Release() = 0;\r
-\r
- virtual ~IDatabase() { };\r
- };\r
-\r
- /* ITransaction is the interface to the transaction connections in IBPP.\r
- * Transaction is the object class you actually use in your programming. A\r
- * Transaction object can be associated with more than one Database,\r
- * allowing for distributed transactions spanning multiple databases,\r
- * possibly located on different servers. IBPP is one among the few\r
- * programming interfaces to Firebird that allows you to support distributed\r
- * transactions. */\r
-\r
- class ITransaction\r
- {\r
- public:\r
- virtual void AttachDatabase(Database db, TAM am = amWrite,\r
- TIL il = ilConcurrency, TLR lr = lrWait, TFF flags = TFF(0)) = 0;\r
- virtual void DetachDatabase(Database db) = 0;\r
- virtual void AddReservation(Database db,\r
- const std::string& table, TTR tr) = 0;\r
-\r
- virtual void Start() = 0;\r
- virtual bool Started() = 0;\r
- virtual void Commit() = 0;\r
- virtual void Rollback() = 0;\r
- virtual void CommitRetain() = 0;\r
- virtual void RollbackRetain() = 0;\r
-\r
- virtual ITransaction* AddRef() = 0;\r
- virtual void Release() = 0;\r
-\r
- virtual ~ITransaction() { };\r
- };\r
-\r
- /*\r
- * Class Row can hold all the values of a row (from a SELECT for instance).\r
- */\r
-\r
- class IRow\r
- {\r
- public:\r
- virtual void SetNull(int) = 0;\r
- virtual void Set(int, bool) = 0;\r
- virtual void Set(int, const void*, int) = 0; // byte buffers\r
- virtual void Set(int, const char*) = 0; // c-string\r
- virtual void Set(int, const std::string&) = 0;\r
- virtual void Set(int, int16_t) = 0;\r
- virtual void Set(int, int32_t) = 0;\r
- virtual void Set(int, int64_t) = 0;\r
- virtual void Set(int, float) = 0;\r
- virtual void Set(int, double) = 0;\r
- virtual void Set(int, const Timestamp&) = 0;\r
- virtual void Set(int, const Date&) = 0;\r
- virtual void Set(int, const Time&) = 0;\r
- virtual void Set(int, const DBKey&) = 0;\r
- virtual void Set(int, const Blob&) = 0;\r
- virtual void Set(int, const Array&) = 0;\r
-\r
- virtual bool IsNull(int) = 0;\r
- virtual bool Get(int, bool&) = 0;\r
- virtual bool Get(int, void*, int&) = 0; // byte buffers\r
- virtual bool Get(int, std::string&) = 0;\r
- virtual bool Get(int, int16_t&) = 0;\r
- virtual bool Get(int, int32_t&) = 0;\r
- virtual bool Get(int, int64_t&) = 0;\r
- virtual bool Get(int, float&) = 0;\r
- virtual bool Get(int, double&) = 0;\r
- virtual bool Get(int, Timestamp&) = 0;\r
- virtual bool Get(int, Date&) = 0;\r
- virtual bool Get(int, Time&) = 0;\r
- virtual bool Get(int, DBKey&) = 0;\r
- virtual bool Get(int, Blob&) = 0;\r
- virtual bool Get(int, Array&) = 0;\r
-\r
- virtual bool IsNull(const std::string&) = 0;\r
- virtual bool Get(const std::string&, bool&) = 0;\r
- virtual bool Get(const std::string&, void*, int&) = 0; // byte buffers\r
- virtual bool Get(const std::string&, std::string&) = 0;\r
- virtual bool Get(const std::string&, int16_t&) = 0;\r
- virtual bool Get(const std::string&, int32_t&) = 0;\r
- virtual bool Get(const std::string&, int64_t&) = 0;\r
- virtual bool Get(const std::string&, float&) = 0;\r
- virtual bool Get(const std::string&, double&) = 0;\r
- virtual bool Get(const std::string&, Timestamp&) = 0;\r
- virtual bool Get(const std::string&, Date&) = 0;\r
- virtual bool Get(const std::string&, Time&) = 0;\r
- virtual bool Get(const std::string&, DBKey&) = 0;\r
- virtual bool Get(const std::string&, Blob&) = 0;\r
- virtual bool Get(const std::string&, Array&) = 0;\r
-\r
- virtual int ColumnNum(const std::string&) = 0;\r
- virtual const char* ColumnName(int) = 0;\r
- virtual const char* ColumnAlias(int) = 0;\r
- virtual const char* ColumnTable(int) = 0;\r
- virtual SDT ColumnType(int) = 0;\r
- virtual int ColumnSubtype(int) = 0;\r
- virtual int ColumnSize(int) = 0;\r
- virtual int ColumnScale(int) = 0;\r
- virtual int Columns() = 0;\r
- \r
- virtual bool ColumnUpdated(int) = 0;\r
- virtual bool Updated() = 0;\r
-\r
- virtual Database DatabasePtr() const = 0;\r
- virtual Transaction TransactionPtr() const = 0;\r
-\r
- virtual IRow* Clone() = 0;\r
- virtual IRow* AddRef() = 0;\r
- virtual void Release() = 0;\r
-\r
- virtual ~IRow() {};\r
- };\r
-\r
- /* IStatement is the interface to the statements execution in IBPP.\r
- * Statement is the object class you actually use in your programming. A\r
- * Statement object is the work horse of IBPP. All your data manipulation\r
- * statements will be done through it. It is also used to access the result\r
- * set of a query (when the statement is such), one row at a time and in\r
- * strict forward direction. */\r
-\r
- class IStatement\r
- {\r
- public:\r
- virtual void Prepare(const std::string&) = 0;\r
- virtual void Execute() = 0;\r
- virtual void Execute(const std::string&) = 0;\r
- virtual void ExecuteImmediate(const std::string&) = 0;\r
- virtual void CursorExecute(const std::string& cursor) = 0;\r
- virtual void CursorExecute(const std::string& cursor, const std::string&) = 0;\r
- virtual bool Fetch() = 0;\r
- virtual bool Fetch(Row&) = 0;\r
- virtual int AffectedRows() = 0;\r
- virtual void Close() = 0;\r
- virtual std::string& Sql() = 0;\r
- virtual STT Type() = 0;\r
-\r
- virtual void SetNull(int) = 0;\r
- virtual void Set(int, bool) = 0;\r
- virtual void Set(int, const void*, int) = 0; // byte buffers\r
- virtual void Set(int, const char*) = 0; // c-string\r
- virtual void Set(int, const std::string&) = 0;\r
- virtual void Set(int, int16_t value) = 0;\r
- virtual void Set(int, int32_t value) = 0;\r
- virtual void Set(int, int64_t value) = 0;\r
- virtual void Set(int, float value) = 0;\r
- virtual void Set(int, double value) = 0;\r
- virtual void Set(int, const Timestamp& value) = 0;\r
- virtual void Set(int, const Date& value) = 0;\r
- virtual void Set(int, const Time& value) = 0;\r
- virtual void Set(int, const DBKey& value) = 0;\r
- virtual void Set(int, const Blob& value) = 0;\r
- virtual void Set(int, const Array& value) = 0;\r
-\r
- virtual bool IsNull(int) = 0;\r
- virtual bool Get(int, bool&) = 0;\r
- virtual bool Get(int, void*, int&) = 0; // byte buffers\r
- virtual bool Get(int, std::string&) = 0;\r
- virtual bool Get(int, int16_t&) = 0;\r
- virtual bool Get(int, int32_t&) = 0;\r
- virtual bool Get(int, int64_t&) = 0;\r
- virtual bool Get(int, float&) = 0;\r
- virtual bool Get(int, double&) = 0;\r
- virtual bool Get(int, Timestamp& value) = 0;\r
- virtual bool Get(int, Date& value) = 0;\r
- virtual bool Get(int, Time& value) = 0;\r
- virtual bool Get(int, DBKey& value) = 0;\r
- virtual bool Get(int, Blob& value) = 0;\r
- virtual bool Get(int, Array& value) = 0;\r
-\r
- virtual bool IsNull(const std::string&) = 0;\r
- virtual bool Get(const std::string&, bool&) = 0;\r
- virtual bool Get(const std::string&, void*, int&) = 0; // byte buffers\r
- virtual bool Get(const std::string&, std::string&) = 0;\r
- virtual bool Get(const std::string&, int16_t&) = 0;\r
- virtual bool Get(const std::string&, int32_t&) = 0;\r
- virtual bool Get(const std::string&, int64_t&) = 0;\r
- virtual bool Get(const std::string&, float&) = 0;\r
- virtual bool Get(const std::string&, double&) = 0;\r
- virtual bool Get(const std::string&, Timestamp& value) = 0;\r
- virtual bool Get(const std::string&, Date& value) = 0;\r
- virtual bool Get(const std::string&, Time& value) = 0;\r
- virtual bool Get(const std::string&, DBKey& value) = 0;\r
- virtual bool Get(const std::string&, Blob& value) = 0;\r
- virtual bool Get(const std::string&, Array& value) = 0;\r
-\r
- virtual int ColumnNum(const std::string&) = 0;\r
- virtual const char* ColumnName(int) = 0;\r
- virtual const char* ColumnAlias(int) = 0;\r
- virtual const char* ColumnTable(int) = 0;\r
- virtual SDT ColumnType(int) = 0;\r
- virtual int ColumnSubtype(int) = 0;\r
- virtual int ColumnSize(int) = 0;\r
- virtual int ColumnScale(int) = 0;\r
- virtual int Columns() = 0;\r
-\r
- virtual SDT ParameterType(int) = 0;\r
- virtual int ParameterSubtype(int) = 0;\r
- virtual int ParameterSize(int) = 0;\r
- virtual int ParameterScale(int) = 0;\r
- virtual int Parameters() = 0;\r
-\r
- virtual void Plan(std::string&) = 0;\r
-\r
- virtual Database DatabasePtr() const = 0;\r
- virtual Transaction TransactionPtr() const = 0;\r
-\r
- virtual IStatement* AddRef() = 0;\r
- virtual void Release() = 0;\r
-\r
- virtual ~IStatement() { };\r
-\r
- // DEPRECATED METHODS (WON'T BE AVAILABLE IN VERSIONS 3.x)\r
- virtual bool Get(int, char*) = 0; // DEPRECATED\r
- virtual bool Get(const std::string&, char*) = 0; // DEPRECATED\r
- virtual bool Get(int, bool*) = 0; // DEPRECATED\r
- virtual bool Get(const std::string&, bool*) = 0; // DEPRECATED\r
- virtual bool Get(int, int16_t*) = 0; // DEPRECATED\r
- virtual bool Get(const std::string&, int16_t*) = 0; // DEPRECATED\r
- virtual bool Get(int, int32_t*) = 0; // DEPRECATED\r
- virtual bool Get(const std::string&, int32_t*) = 0; // DEPRECATED\r
- virtual bool Get(int, int64_t*) = 0; // DEPRECATED\r
- virtual bool Get(const std::string&, int64_t*) = 0; // DEPRECATED\r
- virtual bool Get(int, float*) = 0; // DEPRECATED\r
- virtual bool Get(const std::string&, float*) = 0; // DEPRECATED\r
- virtual bool Get(int, double*) = 0; // DEPRECATED\r
- virtual bool Get(const std::string&, double*) = 0; // DEPRECATED\r
- };\r
- \r
- class IEvents\r
- {\r
- public:\r
- virtual void Add(const std::string&, EventInterface*) = 0;\r
- virtual void Drop(const std::string&) = 0;\r
- virtual void List(std::vector<std::string>&) = 0;\r
- virtual void Clear() = 0; // Drop all events\r
- virtual void Dispatch() = 0; // Dispatch events (calls handlers)\r
-\r
- virtual Database DatabasePtr() const = 0;\r
-\r
- virtual IEvents* AddRef() = 0;\r
- virtual void Release() = 0;\r
-\r
- virtual ~IEvents() { };\r
- };\r
- \r
- /* Class EventInterface is merely a pure interface.\r
- * It is _not_ implemented by IBPP. It is only a base class definition from\r
- * which your own event interface classes have to derive from.\r
- * Please read the reference guide at http://www.ibpp.org for more info. */\r
-\r
- class EventInterface\r
- {\r
- public:\r
- virtual void ibppEventHandler(Events, const std::string&, int) = 0;\r
- virtual ~EventInterface() { };\r
- };\r
-\r
- // --- Factories ---\r
- // These methods are the only way to get one of the above\r
- // Interfaces. They are at the heart of how you program using IBPP. For\r
- // instance, to get access to a database, you'll write code similar to this:\r
- // {\r
- // Database db = DatabaseFactory("server", "databasename",\r
- // "user", "password");\r
- // db->Connect();\r
- // ...\r
- // db->Disconnect();\r
- // }\r
-\r
- Service ServiceFactory(const std::string& ServerName,\r
- const std::string& UserName, const std::string& UserPassword);\r
-\r
- Database DatabaseFactory(const std::string& ServerName,\r
- const std::string& DatabaseName, const std::string& UserName,\r
- const std::string& UserPassword, const std::string& RoleName,\r
- const std::string& CharSet, const std::string& CreateParams);\r
-\r
- inline Database DatabaseFactory(const std::string& ServerName,\r
- const std::string& DatabaseName, const std::string& UserName,\r
- const std::string& UserPassword)\r
- { return DatabaseFactory(ServerName, DatabaseName, UserName, UserPassword, "", "", ""); }\r
-\r
- Transaction TransactionFactory(Database db, TAM am = amWrite,\r
- TIL il = ilConcurrency, TLR lr = lrWait, TFF flags = TFF(0));\r
-\r
- Statement StatementFactory(Database db, Transaction tr,\r
- const std::string& sql);\r
-\r
- inline Statement StatementFactory(Database db, Transaction tr)\r
- { return StatementFactory(db, tr, ""); }\r
-\r
- Blob BlobFactory(Database db, Transaction tr);\r
- \r
- Array ArrayFactory(Database db, Transaction tr);\r
- \r
- Events EventsFactory(Database db);\r
-\r
- /* IBPP uses a self initialization system. Each time an object that may\r
- * require the usage of the Interbase client C-API library is used, the\r
- * library internal handling details are automatically initialized, if not\r
- * already done. You can kick this initialization at the start of an\r
- * application by calling IBPP::CheckVersion(). This is recommended, because\r
- * IBPP::CheckVersion will assure you that YOUR code has been compiled\r
- * against a compatible version of the library. */\r
-\r
- bool CheckVersion(uint32_t);\r
- int GDSVersion();\r
- \r
- /* On Win32 platform, ClientLibSearchPaths() allows to setup\r
- * one or multiple additional paths (separated with a ';') where IBPP\r
- * will look for the client library (before the default implicit search\r
- * locations). This is usefull for applications distributed with a 'private'\r
- * copy of Firebird, when the registry is useless to identify the location\r
- * from where to attempt loading the fbclient.dll / gds32.dll.\r
- * If called, this function must be called *early* by the application,\r
- * before *any* other function or object methods of IBPP.\r
- * Currently, this is a NO-OP on platforms other than Win32. */\r
- \r
- void ClientLibSearchPaths(const std::string&);\r
-\r
- /* Finally, here are some date and time conversion routines used by IBPP and\r
- * that may be helpful at the application level. They do not depend on\r
- * anything related to Firebird/Interbase. Just a bonus. dtoi and itod\r
- * return false on invalid parameters or out of range conversions. */\r
-\r
- bool dtoi(int date, int* py, int* pm, int* pd);\r
- bool itod(int* pdate, int year, int month, int day);\r
- void ttoi(int itime, int* phour, int* pminute, int* psecond, int* ptt);\r
- void itot(int* ptime, int hour, int minute, int second = 0, int tenthousandths = 0);\r
-\r
-}\r
-\r
-#endif\r
-\r
-//\r
-// EOF\r
-//\r
--- /dev/null
+///////////////////////////////////////////////////////////////////////////////\r
+//\r
+// File : $Id: ibpp.h,v 1.3 2007/10/28 11:17:44 nobunaga Exp $\r
+// Subject : IBPP public header file. This is _the_ only file you include in\r
+// your application files when developing with IBPP.\r
+//\r
+///////////////////////////////////////////////////////////////////////////////\r
+//\r
+// (C) Copyright 2000-2006 T.I.P. Group S.A. and the IBPP Team (www.ibpp.org)\r
+//\r
+// The contents of this file are subject to the IBPP License (the "License");\r
+// you may not use this file except in compliance with the License. You may\r
+// obtain a copy of the License at http://www.ibpp.org or in the 'license.txt'\r
+// file which must have been distributed along with this file.\r
+//\r
+// This software, distributed under the License, is distributed on an "AS IS"\r
+// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the\r
+// License for the specific language governing rights and limitations\r
+// under the License.\r
+//\r
+// Contributor(s):\r
+//\r
+// Olivier Mascia, main coding\r
+// Matt Hortman, initial linux port\r
+// Mark Jordan, design contributions\r
+// Maxim Abrashkin, enhancement patches\r
+// Torsten Martinsen, enhancement patches\r
+// Michael Hieke, darwin (OS X) port, enhancement patches\r
+// Val Samko, enhancement patches and debugging\r
+// Mike Nordell, invaluable C++ advices\r
+// Claudio Valderrama, help with not-so-well documented IB/FB features\r
+// Many others, excellent suggestions, bug finding, and support\r
+//\r
+///////////////////////////////////////////////////////////////////////////////\r
+//\r
+// COMMENTS\r
+// Tabulations should be set every four characters when editing this file.\r
+//\r
+// When compiling a project using IBPP, the following defines should be made\r
+// on the command-line (or in makefiles) according to the OS platform and\r
+// compiler used.\r
+//\r
+// Select the platform: IBPP_WINDOWS | IBPP_LINUX | IBPP_DARWIN\r
+//\r
+///////////////////////////////////////////////////////////////////////////////\r
+\r
+#ifndef __IBPP_H__\r
+#define __IBPP_H__\r
+\r
+#if !defined(IBPP_WINDOWS) && !defined(IBPP_LINUX) && !defined(IBPP_DARWIN)\r
+#error Please define IBPP_WINDOWS/IBPP_LINUX/IBPP_DARWIN before compiling !\r
+#endif\r
+\r
+#if !defined(__BCPLUSPLUS__) && !defined(__GNUC__) && !defined(_MSC_VER) && !defined(__DMC__)
+#error Your compiler is not recognized.\r
+#endif\r
+\r
+#if defined(IBPP_LINUX) || defined(IBPP_DARWIN)\r
+#define IBPP_UNIX // IBPP_UNIX stands as a common denominator to *NIX flavours\r
+#endif\r
+\r
+// IBPP is written for 32 bits systems or higher.\r
+// The standard type 'int' is assumed to be at least 32 bits.\r
+// And the standard type 'short' is assumed to be exactly 16 bits.\r
+// Everywhere possible, where the exact size of an integer does not matter,\r
+// the standard type 'int' is used. And where an exact integer size is required\r
+// the standard exact precision types definitions of C 99 standard are used.\r
+\r
+#if defined(_MSC_VER) || defined(__DMC__) || defined(__BCPLUSPLUS__)\r
+// C99 §7.18.1.1 Exact-width integer types (only those used by IBPP)\r
+#if defined(_MSC_VER) && (_MSC_VER < 1300) // MSVC 6 should be < 1300\r
+ typedef short int16_t;\r
+ typedef int int32_t;\r
+ typedef unsigned int uint32_t;\r
+#else\r
+ typedef __int16 int16_t;\r
+ typedef __int32 int32_t;\r
+ typedef unsigned __int32 uint32_t;\r
+#endif\r
+ typedef __int64 int64_t;\r
+#else\r
+ #include <stg/os_int.h> // C99 (§7.18) integer types definitions\r
+#endif\r
+\r
+#if !defined(_)\r
+#define _(s) s\r
+#endif\r
+\r
+#include <exception>\r
+#include <string>\r
+#include <vector>\r
+\r
+namespace IBPP\r
+{\r
+ // Typically you use this constant in a call IBPP::CheckVersion as in:\r
+ // if (! IBPP::CheckVersion(IBPP::Version)) { throw .... ; }\r
+ const uint32_t Version = (2<<24) + (5<<16) + (3<<8) + 0; // Version == 2.5.3.0\r
+\r
+ // Dates range checking\r
+ const int MinDate = -693594; // 1 JAN 0001\r
+ const int MaxDate = 2958464; // 31 DEC 9999\r
+ \r
+ // Transaction Access Modes\r
+ enum TAM {amWrite, amRead};\r
+\r
+ // Transaction Isolation Levels\r
+ enum TIL {ilConcurrency, ilReadDirty, ilReadCommitted, ilConsistency};\r
+\r
+ // Transaction Lock Resolution\r
+ enum TLR {lrWait, lrNoWait};\r
+\r
+ // Transaction Table Reservation\r
+ enum TTR {trSharedWrite, trSharedRead, trProtectedWrite, trProtectedRead};\r
+\r
+ // Prepared Statement Types\r
+ enum STT {stUnknown, stUnsupported,\r
+ stSelect, stInsert, stUpdate, stDelete, stDDL, stExecProcedure,\r
+ stSelectUpdate, stSetGenerator, stSavePoint};\r
+\r
+ // SQL Data Types\r
+ enum SDT {sdArray, sdBlob, sdDate, sdTime, sdTimestamp, sdString,\r
+ sdSmallint, sdInteger, sdLargeint, sdFloat, sdDouble};\r
+\r
+ // Array Data Types\r
+ enum ADT {adDate, adTime, adTimestamp, adString,\r
+ adBool, adInt16, adInt32, adInt64, adFloat, adDouble};\r
+\r
+ // Database::Shutdown Modes\r
+ enum DSM {dsForce, dsDenyTrans, dsDenyAttach};\r
+\r
+ // Service::StartBackup && Service::StartRestore Flags\r
+ enum BRF {\r
+ brVerbose = 0x1,\r
+ // Backup flags\r
+ brIgnoreChecksums = 0x100, brIgnoreLimbo = 0x200,\r
+ brMetadataOnly = 0x400, brNoGarbageCollect = 0x800,\r
+ brNonTransportable = 0x1000, brConvertExtTables = 0x2000,\r
+ // Restore flags\r
+ brReplace = 0x10000, brDeactivateIdx = 0x20000,\r
+ brNoShadow = 0x40000, brNoValidity = 0x80000,\r
+ brPerTableCommit = 0x100000, brUseAllSpace = 0x200000\r
+ };\r
+\r
+ // Service::Repair Flags\r
+ enum RPF\r
+ {\r
+ // Mandatory and mutually exclusives\r
+ rpMendRecords = 0x1, rpValidatePages = 0x2, rpValidateFull = 0x4,\r
+ // Options\r
+ rpReadOnly = 0x100, rpIgnoreChecksums = 0x200, rpKillShadows = 0x400\r
+ };\r
+\r
+ // TransactionFactory Flags\r
+ enum TFF {tfIgnoreLimbo = 0x1, tfAutoCommit = 0x2, tfNoAutoUndo = 0x4};\r
+\r
+ /* IBPP never return any error codes. It throws exceptions.\r
+ * On database engine reported errors, an IBPP::SQLException is thrown.\r
+ * In all other cases, IBPP throws IBPP::LogicException.\r
+ * Also note that the runtime and the language might also throw exceptions\r
+ * while executing some IBPP methods. A failing new operator will throw\r
+ * std::bad_alloc, IBPP does nothing to alter the standard behaviour.\r
+ *\r
+ * std::exception\r
+ * |\r
+ * IBPP::Exception\r
+ * / \\r
+ * IBPP::LogicException IBPP::SQLException\r
+ * |\r
+ * IBPP::WrongType\r
+ */\r
+\r
+ class Exception : public std::exception\r
+ {\r
+ public:\r
+ virtual const char* Origin() const throw() = 0;\r
+ virtual const char* ErrorMessage() const throw() = 0; // Deprecated, use what()\r
+ virtual const char* what() const throw() = 0;\r
+ virtual ~Exception() throw();\r
+ };\r
+\r
+ class LogicException : public Exception\r
+ {\r
+ public:\r
+ virtual ~LogicException() throw();\r
+ };\r
+\r
+ class SQLException : public Exception\r
+ {\r
+ public:\r
+ virtual int SqlCode() const throw() = 0;\r
+ virtual int EngineCode() const throw() = 0;\r
+ \r
+ virtual ~SQLException() throw();\r
+ };\r
+\r
+ class WrongType : public LogicException\r
+ {\r
+ public:\r
+ virtual ~WrongType() throw();\r
+ };\r
+ \r
+ /* Classes Date, Time, Timestamp and DBKey are 'helper' classes. They help\r
+ * in retrieving or setting some special SQL types. Dates, times and dbkeys\r
+ * are often read and written as strings in SQL scripts. When programming\r
+ * with IBPP, we handle those data with these specific classes, which\r
+ * enhance their usefullness and free us of format problems (M/D/Y, D/M/Y,\r
+ * Y-M-D ?, and so on...). */\r
+\r
+ /* Class Date represent purely a Date (no time part specified). It is\r
+ * usefull in interactions with the SQL DATE type of Interbase. You can add\r
+ * or substract a number from a Date, that will modify it to represent the\r
+ * correct date, X days later or sooner. All the Y2K details taken into\r
+ * account.\r
+ * The full range goes from integer values IBPP::MinDate to IBPP::MaxDate\r
+ * which means from 01 Jan 0001 to 31 Dec 9999. ( Which is inherently\r
+ * incorrect as this assumes Gregorian calendar. ) */\r
+ \r
+ class Timestamp; // Cross-reference between Timestamp, Date and Time\r
+ \r
+ class Date\r
+ {\r
+ protected:\r
+ int mDate; // The date : 1 == 1 Jan 1900\r
+\r
+ public:\r
+ void Clear() { mDate = MinDate - 1; };\r
+ void Today();\r
+ void SetDate(int year, int month, int day);\r
+ void SetDate(int dt);\r
+ void GetDate(int& year, int& month, int& day) const;\r
+ int GetDate() const { return mDate; }\r
+ int Year() const;\r
+ int Month() const;\r
+ int Day() const;\r
+ void Add(int days);\r
+ void StartOfMonth();\r
+ void EndOfMonth();\r
+ \r
+ Date() { Clear(); };\r
+ Date(int dt) { SetDate(dt); }\r
+ Date(int year, int month, int day);\r
+ Date(const Date&); // Copy Constructor\r
+ Date& operator=(const Timestamp&); // Timestamp Assignment operator\r
+ Date& operator=(const Date&); // Date Assignment operator\r
+\r
+ bool operator==(const Date& rv) const { return mDate == rv.GetDate(); }\r
+ bool operator!=(const Date& rv) const { return mDate != rv.GetDate(); }\r
+ bool operator<(const Date& rv) const { return mDate < rv.GetDate(); }\r
+ bool operator>(const Date& rv) const { return mDate > rv.GetDate(); }\r
+\r
+ virtual ~Date() { };\r
+ };\r
+\r
+ /* Class Time represent purely a Time. It is usefull in interactions\r
+ * with the SQL TIME type of Interbase. */\r
+\r
+ class Time\r
+ {\r
+ protected:\r
+ int mTime; // The time, in ten-thousandths of seconds since midnight\r
+\r
+ public:\r
+ void Clear() { mTime = 0; }\r
+ void Now();\r
+ void SetTime(int hour, int minute, int second, int tenthousandths = 0);\r
+ void SetTime(int tm);\r
+ void GetTime(int& hour, int& minute, int& second) const;\r
+ void GetTime(int& hour, int& minute, int& second, int& tenthousandths) const;\r
+ int GetTime() const { return mTime; }\r
+ int Hours() const;\r
+ int Minutes() const;\r
+ int Seconds() const;\r
+ int SubSeconds() const; // Actually tenthousandths of seconds\r
+ Time() { Clear(); }\r
+ Time(int tm) { SetTime(tm); }\r
+ Time(int hour, int minute, int second, int tenthousandths = 0);\r
+ Time(const Time&); // Copy Constructor\r
+ Time& operator=(const Timestamp&); // Timestamp Assignment operator\r
+ Time& operator=(const Time&); // Time Assignment operator\r
+\r
+ bool operator==(const Time& rv) const { return mTime == rv.GetTime(); }\r
+ bool operator!=(const Time& rv) const { return mTime != rv.GetTime(); }\r
+ bool operator<(const Time& rv) const { return mTime < rv.GetTime(); }\r
+ bool operator>(const Time& rv) const { return mTime > rv.GetTime(); }\r
+\r
+ virtual ~Time() { };\r
+ };\r
+\r
+ /* Class Timestamp represent a date AND a time. It is usefull in\r
+ * interactions with the SQL TIMESTAMP type of Interbase. This class\r
+ * inherits from Date and Time and completely inline implements its small\r
+ * specific details. */\r
+\r
+ class Timestamp : public Date, public Time\r
+ {\r
+ public:\r
+ void Clear() { Date::Clear(); Time::Clear(); }\r
+ void Today() { Date::Today(); Time::Clear(); }\r
+ void Now() { Date::Today(); Time::Now(); }\r
+\r
+ Timestamp() { Clear(); }\r
+\r
+ Timestamp(int y, int m, int d)\r
+ { Date::SetDate(y, m, d); Time::Clear(); }\r
+\r
+ Timestamp(int y, int mo, int d, int h, int mi, int s, int t = 0)\r
+ { Date::SetDate(y, mo, d); Time::SetTime(h, mi, s, t); }\r
+\r
+ Timestamp(const Timestamp& rv)\r
+ : Date(rv.mDate), Time(rv.mTime) {} // Copy Constructor\r
+\r
+ Timestamp(const Date& rv)\r
+ { mDate = rv.GetDate(); mTime = 0; }\r
+\r
+ Timestamp(const Time& rv)\r
+ { mDate = 0; mTime = rv.GetTime(); }\r
+\r
+ Timestamp& operator=(const Timestamp& rv) // Timestamp Assignment operator\r
+ { mDate = rv.mDate; mTime = rv.mTime; return *this; }\r
+\r
+ Timestamp& operator=(const Date& rv) // Date Assignment operator\r
+ { mDate = rv.GetDate(); return *this; }\r
+\r
+ Timestamp& operator=(const Time& rv) // Time Assignment operator\r
+ { mTime = rv.GetTime(); return *this; }\r
+\r
+ bool operator==(const Timestamp& rv) const\r
+ { return (mDate == rv.GetDate()) && (mTime == rv.GetTime()); }\r
+\r
+ bool operator!=(const Timestamp& rv) const\r
+ { return (mDate != rv.GetDate()) || (mTime != rv.GetTime()); }\r
+\r
+ bool operator<(const Timestamp& rv) const\r
+ { return (mDate < rv.GetDate()) ||\r
+ (mDate == rv.GetDate() && mTime < rv.GetTime()); }\r
+\r
+ bool operator>(const Timestamp& rv) const\r
+ { return (mDate > rv.GetDate()) ||\r
+ (mDate == rv.GetDate() && mTime > rv.GetTime()); }\r
+\r
+ ~Timestamp() { }\r
+ };\r
+\r
+ /* Class DBKey can store a DBKEY, that special value which the hidden\r
+ * RDB$DBKEY can give you from a select statement. A DBKey is nothing\r
+ * specific to IBPP. It's a feature of the Firebird database engine. See its\r
+ * documentation for more information. */\r
+\r
+ class DBKey\r
+ {\r
+ private:\r
+ std::string mDBKey; // Stores the binary DBKey\r
+ mutable std::string mString;// String (temporary) representation of it\r
+\r
+ public:\r
+ void Clear();\r
+ int Size() const { return (int)mDBKey.size(); }\r
+ void SetKey(const void*, int size);\r
+ void GetKey(void*, int size) const;\r
+ const char* AsString() const;\r
+\r
+ DBKey& operator=(const DBKey&); // Assignment operator\r
+ DBKey(const DBKey&); // Copy Constructor\r
+ DBKey() { }\r
+ ~DBKey() { }\r
+ };\r
+\r
+ /* Class User wraps all the information about a user that the engine can manage. */\r
+\r
+ class User\r
+ {\r
+ public:\r
+ std::string username;\r
+ std::string password;\r
+ std::string firstname;\r
+ std::string middlename;\r
+ std::string lastname;\r
+ uint32_t userid; // Only relevant on unixes\r
+ uint32_t groupid; // Only relevant on unixes\r
+\r
+ private:\r
+ void copyfrom(const User& r);\r
+\r
+ public:\r
+ void clear();\r
+ User& operator=(const User& r) { copyfrom(r); return *this; }\r
+ User(const User& r) { copyfrom(r); }\r
+ User() : userid(0), groupid(0) { }\r
+ ~User() { };\r
+ };\r
+\r
+ // Interface Wrapper\r
+ template <class T>\r
+ class Ptr\r
+ {\r
+ private:\r
+ T* mObject;\r
+\r
+ public:\r
+ void clear()\r
+ {\r
+ if (mObject != 0) { mObject->Release(); mObject = 0; }\r
+ }\r
+\r
+ T* intf() const { return mObject; }\r
+ T* operator->() const { return mObject; }\r
+\r
+ bool operator==(const T* p) const { return mObject == p; }\r
+ bool operator==(const Ptr& r) const { return mObject == r.mObject; }\r
+ bool operator!=(const T* p) const { return mObject != p; }\r
+ bool operator!=(const Ptr& r) const { return mObject != r.mObject; }\r
+\r
+ Ptr& operator=(T* p)\r
+ {\r
+ // AddRef _before_ Release gives correct behaviour on self-assigns\r
+ T* tmp = (p == 0 ? 0 : p->AddRef()); // Take care of 0\r
+ if (mObject != 0) mObject->Release();\r
+ mObject = tmp; return *this;\r
+ }\r
+\r
+ Ptr& operator=(const Ptr& r)\r
+ {\r
+ // AddRef _before_ Release gives correct behaviour on self-assigns\r
+ T* tmp = (r.intf() == 0 ? 0 : r->AddRef());// Take care of 0\r
+ if (mObject != 0) mObject->Release();\r
+ mObject = tmp; return *this;\r
+ }\r
+\r
+ Ptr(T* p) : mObject(p == 0 ? 0 : p->AddRef()) { }\r
+ Ptr(const Ptr& r) : mObject(r.intf() == 0 ? 0 : r->AddRef()) { }\r
+\r
+ Ptr() : mObject(0) { }\r
+ ~Ptr() { clear(); }\r
+ };\r
+\r
+ // --- Interface Classes --- //\r
+\r
+ /* Interfaces IBlob, IArray, IService, IDatabase, ITransaction and\r
+ * IStatement are at the core of IBPP. Though it is possible to program your\r
+ * applications by using theses interfaces directly (as was the case with\r
+ * IBPP 1.x), you should refrain from using them and prefer the new IBPP\r
+ * Objects Blob, Array, ... (without the I in front). Those new objects are\r
+ * typedef'd right after each interface class definition as you can read\r
+ * below. If you program using the Blob (instead of the IBlob interface\r
+ * itself), you'll never have to care about AddRef/Release and you'll never\r
+ * have to care about deleting your objects. */\r
+\r
+ class IBlob; typedef Ptr<IBlob> Blob;\r
+ class IArray; typedef Ptr<IArray> Array;\r
+ class IService; typedef Ptr<IService> Service;\r
+ class IDatabase; typedef Ptr<IDatabase> Database;\r
+ class ITransaction; typedef Ptr<ITransaction> Transaction;\r
+ class IStatement; typedef Ptr<IStatement> Statement;\r
+ class IEvents; typedef Ptr<IEvents> Events;\r
+ class IRow; typedef Ptr<IRow> Row;\r
+\r
+ /* IBlob is the interface to the blob capabilities of IBPP. Blob is the\r
+ * object class you actually use in your programming. In Firebird, at the\r
+ * row level, a blob is merely a handle to a blob, stored elsewhere in the\r
+ * database. Blob allows you to retrieve such a handle and then read from or\r
+ * write to the blob, much in the same manner than you would do with a file. */\r
+\r
+ class IBlob\r
+ {\r
+ public:\r
+ virtual void Create() = 0;\r
+ virtual void Open() = 0;\r
+ virtual void Close() = 0;\r
+ virtual void Cancel() = 0;\r
+ virtual int Read(void*, int size) = 0;\r
+ virtual void Write(const void*, int size) = 0;\r
+ virtual void Info(int* Size, int* Largest, int* Segments) = 0;\r
+ \r
+ virtual void Save(const std::string& data) = 0;\r
+ virtual void Load(std::string& data) = 0;\r
+\r
+ virtual Database DatabasePtr() const = 0;\r
+ virtual Transaction TransactionPtr() const = 0;\r
+\r
+ virtual IBlob* AddRef() = 0;\r
+ virtual void Release() = 0;\r
+\r
+ virtual ~IBlob() { };\r
+ };\r
+\r
+ /* IArray is the interface to the array capabilities of IBPP. Array is the\r
+ * object class you actually use in your programming. With an Array object, you\r
+ * can create, read and write Interbase Arrays, as a whole or in slices. */\r
+\r
+ class IArray\r
+ {\r
+ public:\r
+ virtual void Describe(const std::string& table, const std::string& column) = 0;\r
+ virtual void ReadTo(ADT, void* buffer, int elemcount) = 0;\r
+ virtual void WriteFrom(ADT, const void* buffer, int elemcount) = 0;\r
+ virtual SDT ElementType() = 0;\r
+ virtual int ElementSize() = 0;\r
+ virtual int ElementScale() = 0;\r
+ virtual int Dimensions() = 0;\r
+ virtual void Bounds(int dim, int* low, int* high) = 0;\r
+ virtual void SetBounds(int dim, int low, int high) = 0;\r
+\r
+ virtual Database DatabasePtr() const = 0;\r
+ virtual Transaction TransactionPtr() const = 0;\r
+\r
+ virtual IArray* AddRef() = 0;\r
+ virtual void Release() = 0;\r
+\r
+ virtual ~IArray() { };\r
+ };\r
+\r
+ /* IService is the interface to the service capabilities of IBPP. Service is\r
+ * the object class you actually use in your programming. With a Service\r
+ * object, you can do some maintenance work of databases and servers\r
+ * (backup, restore, create/update users, ...) */\r
+\r
+ class IService\r
+ {\r
+ public:\r
+ virtual void Connect() = 0;\r
+ virtual bool Connected() = 0;\r
+ virtual void Disconnect() = 0;\r
+\r
+ virtual void GetVersion(std::string& version) = 0;\r
+\r
+ virtual void AddUser(const User&) = 0;\r
+ virtual void GetUser(User&) = 0;\r
+ virtual void GetUsers(std::vector<User>&) = 0;\r
+ virtual void ModifyUser(const User&) = 0;\r
+ virtual void RemoveUser(const std::string& username) = 0;\r
+\r
+ virtual void SetPageBuffers(const std::string& dbfile, int buffers) = 0;\r
+ virtual void SetSweepInterval(const std::string& dbfile, int sweep) = 0;\r
+ virtual void SetSyncWrite(const std::string& dbfile, bool) = 0;\r
+ virtual void SetReadOnly(const std::string& dbfile, bool) = 0;\r
+ virtual void SetReserveSpace(const std::string& dbfile, bool) = 0;\r
+\r
+ virtual void Shutdown(const std::string& dbfile, DSM mode, int sectimeout) = 0;\r
+ virtual void Restart(const std::string& dbfile) = 0;\r
+ virtual void Sweep(const std::string& dbfile) = 0;\r
+ virtual void Repair(const std::string& dbfile, RPF flags) = 0;\r
+\r
+ virtual void StartBackup(const std::string& dbfile,\r
+ const std::string& bkfile, BRF flags = BRF(0)) = 0;\r
+ virtual void StartRestore(const std::string& bkfile, const std::string& dbfile,\r
+ int pagesize = 0, BRF flags = BRF(0)) = 0;\r
+\r
+ virtual const char* WaitMsg() = 0; // With reporting (does not block)\r
+ virtual void Wait() = 0; // Without reporting (does block)\r
+\r
+ virtual IService* AddRef() = 0;\r
+ virtual void Release() = 0;\r
+\r
+ virtual ~IService() { };\r
+ };\r
+\r
+ /* IDatabase is the interface to the database connections in IBPP. Database\r
+ * is the object class you actually use in your programming. With a Database\r
+ * object, you can create/drop/connect databases. */\r
+\r
+ class EventInterface; // Cross-reference between EventInterface and IDatabase\r
+ \r
+ class IDatabase\r
+ {\r
+ public:\r
+ virtual const char* ServerName() const = 0;\r
+ virtual const char* DatabaseName() const = 0;\r
+ virtual const char* Username() const = 0;\r
+ virtual const char* UserPassword() const = 0;\r
+ virtual const char* RoleName() const = 0;\r
+ virtual const char* CharSet() const = 0;\r
+ virtual const char* CreateParams() const = 0;\r
+\r
+ virtual void Info(int* ODS, int* ODSMinor, int* PageSize,\r
+ int* Pages, int* Buffers, int* Sweep, bool* Sync,\r
+ bool* Reserve) = 0;\r
+ virtual void Statistics(int* Fetches, int* Marks,\r
+ int* Reads, int* Writes) = 0;\r
+ virtual void Counts(int* Insert, int* Update, int* Delete, \r
+ int* ReadIdx, int* ReadSeq) = 0;\r
+ virtual void Users(std::vector<std::string>& users) = 0;\r
+ virtual int Dialect() = 0;\r
+\r
+ virtual void Create(int dialect) = 0;\r
+ virtual void Connect() = 0;\r
+ virtual bool Connected() = 0;\r
+ virtual void Inactivate() = 0;\r
+ virtual void Disconnect() = 0;\r
+ virtual void Drop() = 0;\r
+\r
+ virtual IDatabase* AddRef() = 0;\r
+ virtual void Release() = 0;\r
+\r
+ virtual ~IDatabase() { };\r
+ };\r
+\r
+ /* ITransaction is the interface to the transaction connections in IBPP.\r
+ * Transaction is the object class you actually use in your programming. A\r
+ * Transaction object can be associated with more than one Database,\r
+ * allowing for distributed transactions spanning multiple databases,\r
+ * possibly located on different servers. IBPP is one among the few\r
+ * programming interfaces to Firebird that allows you to support distributed\r
+ * transactions. */\r
+\r
+ class ITransaction\r
+ {\r
+ public:\r
+ virtual void AttachDatabase(Database db, TAM am = amWrite,\r
+ TIL il = ilConcurrency, TLR lr = lrWait, TFF flags = TFF(0)) = 0;\r
+ virtual void DetachDatabase(Database db) = 0;\r
+ virtual void AddReservation(Database db,\r
+ const std::string& table, TTR tr) = 0;\r
+\r
+ virtual void Start() = 0;\r
+ virtual bool Started() = 0;\r
+ virtual void Commit() = 0;\r
+ virtual void Rollback() = 0;\r
+ virtual void CommitRetain() = 0;\r
+ virtual void RollbackRetain() = 0;\r
+\r
+ virtual ITransaction* AddRef() = 0;\r
+ virtual void Release() = 0;\r
+\r
+ virtual ~ITransaction() { };\r
+ };\r
+\r
+ /*\r
+ * Class Row can hold all the values of a row (from a SELECT for instance).\r
+ */\r
+\r
+ class IRow\r
+ {\r
+ public:\r
+ virtual void SetNull(int) = 0;\r
+ virtual void Set(int, bool) = 0;\r
+ virtual void Set(int, const void*, int) = 0; // byte buffers\r
+ virtual void Set(int, const char*) = 0; // c-string\r
+ virtual void Set(int, const std::string&) = 0;\r
+ virtual void Set(int, int16_t) = 0;\r
+ virtual void Set(int, int32_t) = 0;\r
+ virtual void Set(int, int64_t) = 0;\r
+ virtual void Set(int, float) = 0;\r
+ virtual void Set(int, double) = 0;\r
+ virtual void Set(int, const Timestamp&) = 0;\r
+ virtual void Set(int, const Date&) = 0;\r
+ virtual void Set(int, const Time&) = 0;\r
+ virtual void Set(int, const DBKey&) = 0;\r
+ virtual void Set(int, const Blob&) = 0;\r
+ virtual void Set(int, const Array&) = 0;\r
+\r
+ virtual bool IsNull(int) = 0;\r
+ virtual bool Get(int, bool&) = 0;\r
+ virtual bool Get(int, void*, int&) = 0; // byte buffers\r
+ virtual bool Get(int, std::string&) = 0;\r
+ virtual bool Get(int, int16_t&) = 0;\r
+ virtual bool Get(int, int32_t&) = 0;\r
+ virtual bool Get(int, int64_t&) = 0;\r
+ virtual bool Get(int, float&) = 0;\r
+ virtual bool Get(int, double&) = 0;\r
+ virtual bool Get(int, Timestamp&) = 0;\r
+ virtual bool Get(int, Date&) = 0;\r
+ virtual bool Get(int, Time&) = 0;\r
+ virtual bool Get(int, DBKey&) = 0;\r
+ virtual bool Get(int, Blob&) = 0;\r
+ virtual bool Get(int, Array&) = 0;\r
+\r
+ virtual bool IsNull(const std::string&) = 0;\r
+ virtual bool Get(const std::string&, bool&) = 0;\r
+ virtual bool Get(const std::string&, void*, int&) = 0; // byte buffers\r
+ virtual bool Get(const std::string&, std::string&) = 0;\r
+ virtual bool Get(const std::string&, int16_t&) = 0;\r
+ virtual bool Get(const std::string&, int32_t&) = 0;\r
+ virtual bool Get(const std::string&, int64_t&) = 0;\r
+ virtual bool Get(const std::string&, float&) = 0;\r
+ virtual bool Get(const std::string&, double&) = 0;\r
+ virtual bool Get(const std::string&, Timestamp&) = 0;\r
+ virtual bool Get(const std::string&, Date&) = 0;\r
+ virtual bool Get(const std::string&, Time&) = 0;\r
+ virtual bool Get(const std::string&, DBKey&) = 0;\r
+ virtual bool Get(const std::string&, Blob&) = 0;\r
+ virtual bool Get(const std::string&, Array&) = 0;\r
+\r
+ virtual int ColumnNum(const std::string&) = 0;\r
+ virtual const char* ColumnName(int) = 0;\r
+ virtual const char* ColumnAlias(int) = 0;\r
+ virtual const char* ColumnTable(int) = 0;\r
+ virtual SDT ColumnType(int) = 0;\r
+ virtual int ColumnSubtype(int) = 0;\r
+ virtual int ColumnSize(int) = 0;\r
+ virtual int ColumnScale(int) = 0;\r
+ virtual int Columns() = 0;\r
+ \r
+ virtual bool ColumnUpdated(int) = 0;\r
+ virtual bool Updated() = 0;\r
+\r
+ virtual Database DatabasePtr() const = 0;\r
+ virtual Transaction TransactionPtr() const = 0;\r
+\r
+ virtual IRow* Clone() = 0;\r
+ virtual IRow* AddRef() = 0;\r
+ virtual void Release() = 0;\r
+\r
+ virtual ~IRow() {};\r
+ };\r
+\r
+ /* IStatement is the interface to the statements execution in IBPP.\r
+ * Statement is the object class you actually use in your programming. A\r
+ * Statement object is the work horse of IBPP. All your data manipulation\r
+ * statements will be done through it. It is also used to access the result\r
+ * set of a query (when the statement is such), one row at a time and in\r
+ * strict forward direction. */\r
+\r
+ class IStatement\r
+ {\r
+ public:\r
+ virtual void Prepare(const std::string&) = 0;\r
+ virtual void Execute() = 0;\r
+ virtual void Execute(const std::string&) = 0;\r
+ virtual void ExecuteImmediate(const std::string&) = 0;\r
+ virtual void CursorExecute(const std::string& cursor) = 0;\r
+ virtual void CursorExecute(const std::string& cursor, const std::string&) = 0;\r
+ virtual bool Fetch() = 0;\r
+ virtual bool Fetch(Row&) = 0;\r
+ virtual int AffectedRows() = 0;\r
+ virtual void Close() = 0;\r
+ virtual std::string& Sql() = 0;\r
+ virtual STT Type() = 0;\r
+\r
+ virtual void SetNull(int) = 0;\r
+ virtual void Set(int, bool) = 0;\r
+ virtual void Set(int, const void*, int) = 0; // byte buffers\r
+ virtual void Set(int, const char*) = 0; // c-string\r
+ virtual void Set(int, const std::string&) = 0;\r
+ virtual void Set(int, int16_t value) = 0;\r
+ virtual void Set(int, int32_t value) = 0;\r
+ virtual void Set(int, int64_t value) = 0;\r
+ virtual void Set(int, float value) = 0;\r
+ virtual void Set(int, double value) = 0;\r
+ virtual void Set(int, const Timestamp& value) = 0;\r
+ virtual void Set(int, const Date& value) = 0;\r
+ virtual void Set(int, const Time& value) = 0;\r
+ virtual void Set(int, const DBKey& value) = 0;\r
+ virtual void Set(int, const Blob& value) = 0;\r
+ virtual void Set(int, const Array& value) = 0;\r
+\r
+ virtual bool IsNull(int) = 0;\r
+ virtual bool Get(int, bool&) = 0;\r
+ virtual bool Get(int, void*, int&) = 0; // byte buffers\r
+ virtual bool Get(int, std::string&) = 0;\r
+ virtual bool Get(int, int16_t&) = 0;\r
+ virtual bool Get(int, int32_t&) = 0;\r
+ virtual bool Get(int, int64_t&) = 0;\r
+ virtual bool Get(int, float&) = 0;\r
+ virtual bool Get(int, double&) = 0;\r
+ virtual bool Get(int, Timestamp& value) = 0;\r
+ virtual bool Get(int, Date& value) = 0;\r
+ virtual bool Get(int, Time& value) = 0;\r
+ virtual bool Get(int, DBKey& value) = 0;\r
+ virtual bool Get(int, Blob& value) = 0;\r
+ virtual bool Get(int, Array& value) = 0;\r
+\r
+ virtual bool IsNull(const std::string&) = 0;\r
+ virtual bool Get(const std::string&, bool&) = 0;\r
+ virtual bool Get(const std::string&, void*, int&) = 0; // byte buffers\r
+ virtual bool Get(const std::string&, std::string&) = 0;\r
+ virtual bool Get(const std::string&, int16_t&) = 0;\r
+ virtual bool Get(const std::string&, int32_t&) = 0;\r
+ virtual bool Get(const std::string&, int64_t&) = 0;\r
+ virtual bool Get(const std::string&, float&) = 0;\r
+ virtual bool Get(const std::string&, double&) = 0;\r
+ virtual bool Get(const std::string&, Timestamp& value) = 0;\r
+ virtual bool Get(const std::string&, Date& value) = 0;\r
+ virtual bool Get(const std::string&, Time& value) = 0;\r
+ virtual bool Get(const std::string&, DBKey& value) = 0;\r
+ virtual bool Get(const std::string&, Blob& value) = 0;\r
+ virtual bool Get(const std::string&, Array& value) = 0;\r
+\r
+ virtual int ColumnNum(const std::string&) = 0;\r
+ virtual const char* ColumnName(int) = 0;\r
+ virtual const char* ColumnAlias(int) = 0;\r
+ virtual const char* ColumnTable(int) = 0;\r
+ virtual SDT ColumnType(int) = 0;\r
+ virtual int ColumnSubtype(int) = 0;\r
+ virtual int ColumnSize(int) = 0;\r
+ virtual int ColumnScale(int) = 0;\r
+ virtual int Columns() = 0;\r
+\r
+ virtual SDT ParameterType(int) = 0;\r
+ virtual int ParameterSubtype(int) = 0;\r
+ virtual int ParameterSize(int) = 0;\r
+ virtual int ParameterScale(int) = 0;\r
+ virtual int Parameters() = 0;\r
+\r
+ virtual void Plan(std::string&) = 0;\r
+\r
+ virtual Database DatabasePtr() const = 0;\r
+ virtual Transaction TransactionPtr() const = 0;\r
+\r
+ virtual IStatement* AddRef() = 0;\r
+ virtual void Release() = 0;\r
+\r
+ virtual ~IStatement() { };\r
+\r
+ // DEPRECATED METHODS (WON'T BE AVAILABLE IN VERSIONS 3.x)\r
+ virtual bool Get(int, char*) = 0; // DEPRECATED\r
+ virtual bool Get(const std::string&, char*) = 0; // DEPRECATED\r
+ virtual bool Get(int, bool*) = 0; // DEPRECATED\r
+ virtual bool Get(const std::string&, bool*) = 0; // DEPRECATED\r
+ virtual bool Get(int, int16_t*) = 0; // DEPRECATED\r
+ virtual bool Get(const std::string&, int16_t*) = 0; // DEPRECATED\r
+ virtual bool Get(int, int32_t*) = 0; // DEPRECATED\r
+ virtual bool Get(const std::string&, int32_t*) = 0; // DEPRECATED\r
+ virtual bool Get(int, int64_t*) = 0; // DEPRECATED\r
+ virtual bool Get(const std::string&, int64_t*) = 0; // DEPRECATED\r
+ virtual bool Get(int, float*) = 0; // DEPRECATED\r
+ virtual bool Get(const std::string&, float*) = 0; // DEPRECATED\r
+ virtual bool Get(int, double*) = 0; // DEPRECATED\r
+ virtual bool Get(const std::string&, double*) = 0; // DEPRECATED\r
+ };\r
+ \r
+ class IEvents\r
+ {\r
+ public:\r
+ virtual void Add(const std::string&, EventInterface*) = 0;\r
+ virtual void Drop(const std::string&) = 0;\r
+ virtual void List(std::vector<std::string>&) = 0;\r
+ virtual void Clear() = 0; // Drop all events\r
+ virtual void Dispatch() = 0; // Dispatch events (calls handlers)\r
+\r
+ virtual Database DatabasePtr() const = 0;\r
+\r
+ virtual IEvents* AddRef() = 0;\r
+ virtual void Release() = 0;\r
+\r
+ virtual ~IEvents() { };\r
+ };\r
+ \r
+ /* Class EventInterface is merely a pure interface.\r
+ * It is _not_ implemented by IBPP. It is only a base class definition from\r
+ * which your own event interface classes have to derive from.\r
+ * Please read the reference guide at http://www.ibpp.org for more info. */\r
+\r
+ class EventInterface\r
+ {\r
+ public:\r
+ virtual void ibppEventHandler(Events, const std::string&, int) = 0;\r
+ virtual ~EventInterface() { };\r
+ };\r
+\r
+ // --- Factories ---\r
+ // These methods are the only way to get one of the above\r
+ // Interfaces. They are at the heart of how you program using IBPP. For\r
+ // instance, to get access to a database, you'll write code similar to this:\r
+ // {\r
+ // Database db = DatabaseFactory("server", "databasename",\r
+ // "user", "password");\r
+ // db->Connect();\r
+ // ...\r
+ // db->Disconnect();\r
+ // }\r
+\r
+ Service ServiceFactory(const std::string& ServerName,\r
+ const std::string& UserName, const std::string& UserPassword);\r
+\r
+ Database DatabaseFactory(const std::string& ServerName,\r
+ const std::string& DatabaseName, const std::string& UserName,\r
+ const std::string& UserPassword, const std::string& RoleName,\r
+ const std::string& CharSet, const std::string& CreateParams);\r
+\r
+ inline Database DatabaseFactory(const std::string& ServerName,\r
+ const std::string& DatabaseName, const std::string& UserName,\r
+ const std::string& UserPassword)\r
+ { return DatabaseFactory(ServerName, DatabaseName, UserName, UserPassword, "", "", ""); }\r
+\r
+ Transaction TransactionFactory(Database db, TAM am = amWrite,\r
+ TIL il = ilConcurrency, TLR lr = lrWait, TFF flags = TFF(0));\r
+\r
+ Statement StatementFactory(Database db, Transaction tr,\r
+ const std::string& sql);\r
+\r
+ inline Statement StatementFactory(Database db, Transaction tr)\r
+ { return StatementFactory(db, tr, ""); }\r
+\r
+ Blob BlobFactory(Database db, Transaction tr);\r
+ \r
+ Array ArrayFactory(Database db, Transaction tr);\r
+ \r
+ Events EventsFactory(Database db);\r
+\r
+ /* IBPP uses a self initialization system. Each time an object that may\r
+ * require the usage of the Interbase client C-API library is used, the\r
+ * library internal handling details are automatically initialized, if not\r
+ * already done. You can kick this initialization at the start of an\r
+ * application by calling IBPP::CheckVersion(). This is recommended, because\r
+ * IBPP::CheckVersion will assure you that YOUR code has been compiled\r
+ * against a compatible version of the library. */\r
+\r
+ bool CheckVersion(uint32_t);\r
+ int GDSVersion();\r
+ \r
+ /* On Win32 platform, ClientLibSearchPaths() allows to setup\r
+ * one or multiple additional paths (separated with a ';') where IBPP\r
+ * will look for the client library (before the default implicit search\r
+ * locations). This is usefull for applications distributed with a 'private'\r
+ * copy of Firebird, when the registry is useless to identify the location\r
+ * from where to attempt loading the fbclient.dll / gds32.dll.\r
+ * If called, this function must be called *early* by the application,\r
+ * before *any* other function or object methods of IBPP.\r
+ * Currently, this is a NO-OP on platforms other than Win32. */\r
+ \r
+ void ClientLibSearchPaths(const std::string&);\r
+\r
+ /* Finally, here are some date and time conversion routines used by IBPP and\r
+ * that may be helpful at the application level. They do not depend on\r
+ * anything related to Firebird/Interbase. Just a bonus. dtoi and itod\r
+ * return false on invalid parameters or out of range conversions. */\r
+\r
+ bool dtoi(int date, int* py, int* pm, int* pd);\r
+ bool itod(int* pdate, int year, int month, int day);\r
+ void ttoi(int itime, int* phour, int* pminute, int* psecond, int* ptt);\r
+ void itot(int* ptime, int hour, int minute, int second = 0, int tenthousandths = 0);\r
+\r
+}\r
+\r
+#endif\r
+\r
+//\r
+// EOF\r
+//\r
--- /dev/null
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Author : Boris Mikhailenko <stg34@stargazer.dp.ua>
+ */
+
+/*
+ $Revision: 1.5 $
+ $Date: 2010/03/04 11:57:11 $
+ $Author: faust $
+*/
+
+
+#ifndef STG_LOCKER_H
+#define STG_LOCKER_H
+
+#include <pthread.h>
+
+#ifdef DEBUG_LOCKER
+
+#include <iostream>
+#include <string>
+#include <pthread.h>
+
+#endif
+
+//-----------------------------------------------------------------------------
+class STG_LOCKER
+{
+public:
+ #ifdef DEBUG_LOCKER
+ STG_LOCKER(pthread_mutex_t * m, const char * __file__, int __line__)
+ : mutex(m),
+ file(__file__),
+ line(__line__),
+ lockerMutex(),
+ lockID(0)
+ #else
+ STG_LOCKER(pthread_mutex_t * m, const char *, int)
+ : mutex(m)
+ #endif
+ {
+ mutex = m;
+ #ifdef DEBUG_LOCKER
+ pthread_mutex_lock(&lockerMutex);
+ file = __file__;
+ line = __line__;
+ if (id == 0)
+ pthread_mutex_init(&lockerMutex, NULL);
+
+ lockID = ++id;
+ std::cout << "Lock: " << lockID << " " << file << ":" << line << " " << mutex << " " << pthread_self() << std::endl;
+ pthread_mutex_unlock(&lockerMutex);
+ #endif
+ pthread_mutex_lock(mutex);
+ };
+
+ ~STG_LOCKER()
+ {
+ pthread_mutex_unlock(mutex);
+ #ifdef DEBUG_LOCKER
+ pthread_mutex_lock(&lockerMutex);
+ std::cout << "Unlock: " << lockID << " " << file << ":" << line << " " << mutex << " " << pthread_self() << std::endl;
+ pthread_mutex_unlock(&lockerMutex);
+ #endif
+ };
+private:
+ STG_LOCKER(const STG_LOCKER & rvalue);
+ STG_LOCKER & operator=(const STG_LOCKER & rvalue);
+
+ pthread_mutex_t * mutex;
+ #ifdef DEBUG_LOCKER
+ std::string file;
+ int line;
+ static pthread_mutex_t lockerMutex;
+ static long long id;
+ long long lockID;
+ #endif
+};
+//-----------------------------------------------------------------------------
+
+#endif //STG_LOCKER_H
$Author: nobunaga $
*/
-
+#ifdef DEBUG_LOCKER
#include <pthread.h>
-#include "locker.h"
-
-#ifdef DEBUG_LOCKER
+#include "stg/locker.h"
long long STG_LOCKER::id = 0;
pthread_mutex_t STG_LOCKER::lockerMutex = PTHREAD_MUTEX_INITIALIZER;
+++ /dev/null
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/*
- * Author : Boris Mikhailenko <stg34@stargazer.dp.ua>
- */
-
-/*
- $Revision: 1.5 $
- $Date: 2010/03/04 11:57:11 $
- $Author: faust $
-*/
-
-
-#ifndef STG_LOCKER_H
-#define STG_LOCKER_H
-
-#include <pthread.h>
-
-#ifdef DEBUG_LOCKER
-
-#include <iostream>
-#include <string>
-#include <pthread.h>
-
-#endif
-
-#include "stg/noncopyable.h"
-//-----------------------------------------------------------------------------
-class STG_LOCKER : private NONCOPYABLE
-{
-public:
- #ifdef DEBUG_LOCKER
- STG_LOCKER(pthread_mutex_t * m, const char * __file__, int __line__)
- : mutex(m),
- file(__file__),
- line(__line__),
- lockID(0)
- #else
- STG_LOCKER(pthread_mutex_t * m, const char *, int)
- : mutex(m)
- #endif
- {
- mutex = m;
- #ifdef DEBUG_LOCKER
- pthread_mutex_lock(&lockerMutex);
- file = __file__;
- line = __line__;
- if (id == 0)
- pthread_mutex_init(&lockerMutex, NULL);
-
- lockID = ++id;
- std::cout << "Lock: " << lockID << " " << file << ":" << line << " " << mutex << " " << pthread_self() << std::endl;
- pthread_mutex_unlock(&lockerMutex);
- #endif
- pthread_mutex_lock(mutex);
- };
-
- ~STG_LOCKER()
- {
- pthread_mutex_unlock(mutex);
- #ifdef DEBUG_LOCKER
- pthread_mutex_lock(&lockerMutex);
- std::cout << "Unlock: " << lockID << " " << file << ":" << line << " " << mutex << " " << pthread_self() << std::endl;
- pthread_mutex_unlock(&lockerMutex);
- #endif
- };
-private:
- pthread_mutex_t * mutex;
- #ifdef DEBUG_LOCKER
- std::string file;
- int line;
- static pthread_mutex_t lockerMutex;
- static long long id;
- long long lockID;
- #endif
-};
-//-----------------------------------------------------------------------------
-
-#endif //STG_LOCKER_H
--- /dev/null
+#ifndef STG_LOGGER_H
+#define STG_LOGGER_H
+
+#include <pthread.h>
+
+#include <string>
+
+const char * LogDate(time_t t);
+//-----------------------------------------------------------------------------
+class STG_LOGGER;
+STG_LOGGER & GetStgLogger();
+//-----------------------------------------------------------------------------
+class STG_LOGGER_LOCKER
+{
+public:
+ STG_LOGGER_LOCKER(pthread_mutex_t * m) : mutex(m) { pthread_mutex_lock(mutex); };
+ ~STG_LOGGER_LOCKER() { pthread_mutex_unlock(mutex); };
+
+private:
+ STG_LOGGER_LOCKER(const STG_LOGGER_LOCKER & rvalue);
+ STG_LOGGER_LOCKER & operator=(const STG_LOGGER_LOCKER & rvalue);
+
+ pthread_mutex_t * mutex;
+};
+//-----------------------------------------------------------------------------
+class STG_LOGGER
+{
+friend STG_LOGGER & GetStgLogger();
+
+public:
+ ~STG_LOGGER();
+ void SetLogFileName(const std::string & fn);
+ void operator()(const char * fmt, ...);
+
+private:
+ STG_LOGGER();
+ STG_LOGGER(const STG_LOGGER & rvalue);
+ STG_LOGGER & operator=(const STG_LOGGER & rvalue);
+
+ const char * LogDate(time_t t);
+
+ std::string fileName;
+ pthread_mutex_t mutex;
+};
+//-----------------------------------------------------------------------------
+
+#endif //STG_LOGGER_H
#include <stdarg.h>
#include <syslog.h>
-#include "logger.h"
+#include "stg/logger.h"
#ifdef STG_TIME
extern const volatile time_t stgTime;
}
//-----------------------------------------------------------------------------
STG_LOGGER::STG_LOGGER()
- : fileName()
+ : fileName(),
+ mutex()
{
pthread_mutex_init(&mutex, NULL);
}
+++ /dev/null
-#ifndef STG_LOGGER_H
-#define STG_LOGGER_H
-
-#include <pthread.h>
-
-#include <string>
-
-#include "stg/noncopyable.h"
-
-const char * LogDate(time_t t);
-//-----------------------------------------------------------------------------
-class STG_LOGGER;
-STG_LOGGER & GetStgLogger();
-//-----------------------------------------------------------------------------
-class STG_LOGGER_LOCKER : private NONCOPYABLE
-{
-public:
- STG_LOGGER_LOCKER(pthread_mutex_t * m) : mutex(m) { pthread_mutex_lock(mutex); };
- ~STG_LOGGER_LOCKER() { pthread_mutex_unlock(mutex); };
-private:
- pthread_mutex_t * mutex;
-};
-//-----------------------------------------------------------------------------
-class STG_LOGGER
-{
-friend STG_LOGGER & GetStgLogger();
-
-public:
- ~STG_LOGGER();
- void SetLogFileName(const std::string & fn);
- void operator()(const char * fmt, ...);
-
-private:
- STG_LOGGER();
- const char * LogDate(time_t t);
-
- std::string fileName;
- pthread_mutex_t mutex;
-};
-//-----------------------------------------------------------------------------
-
-#endif //STG_LOGGER_H
LIBS = $(LIB_THREAD)
+LIB_INCS = -I ../locker.lib/include \
+ -I ../common.lib/include
+
include ../Makefile.in
test: all
--- /dev/null
+ /*
+ $Revision: 1.8 $
+ $Date: 2008/05/10 11:59:53 $
+ $Author: nobunaga $
+ */
+
+#ifndef PINGER_H
+#define PINGER_H
+
+#include <ctime>
+#include <string>
+#include <list>
+#include <map>
+
+#ifdef LINUX
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/ip_icmp.h>
+#endif
+
+#if defined (FREE_BSD) || defined (FREE_BSD5)
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_icmp.h>
+#include <netinet/ip_var.h>
+#include <arpa/inet.h>
+#endif
+
+#include "stg/os_int.h"
+
+//-----------------------------------------------------------------------------
+struct ICMP_HDR
+{
+uint8_t type;
+uint8_t code;
+uint16_t checksum;
+union
+ {
+ struct
+ {
+ uint16_t id;
+ uint16_t sequence;
+ } echo;
+ uint32_t gateway;
+ struct
+ {
+ uint16_t unused;
+ uint16_t mtu;
+ } frag;
+ } un;
+};
+//-----------------------------------------------------------------------------
+struct IP_HDR
+{
+ uint8_t ihl:4,
+ version:4;
+ uint8_t tos;
+ uint16_t tot_len;
+ uint16_t id;
+ uint16_t frag_off;
+ uint8_t ttl;
+ uint8_t protocol;
+ uint16_t check;
+ uint32_t saddr;
+ uint32_t daddr;
+};
+//-----------------------------------------------------------------------------
+struct PING_IP_TIME
+{
+uint32_t ip;
+time_t pingTime;
+};
+//-----------------------------------------------------------------------------
+
+#define PING_DATA_LEN (64)
+//-----------------------------------------------------------------------------
+struct PING_MESSAGE
+{
+ ICMP_HDR hdr;
+ char msg[PING_DATA_LEN];
+};
+//-----------------------------------------------------------------------------
+class STG_PINGER
+{
+public:
+ STG_PINGER(time_t delay = 15);
+ ~STG_PINGER();
+
+ int Start();
+ int Stop();
+ void AddIP(uint32_t ip);
+ void DelIP(uint32_t ip);
+ int GetPingIPNum() const;
+ void PrintAllIP();
+ int GetIPTime(uint32_t ip, time_t * t) const;
+ void SetDelayTime(time_t d) { delay = d; }
+ time_t GetDelayTime() const { return delay; }
+ const std::string & GetStrError() const { return errorStr; }
+
+private:
+ uint16_t PingCheckSum(void * data, int len);
+ int SendPing(uint32_t ip);
+ uint32_t RecvPing();
+ void RealAddIP();
+ void RealDelIP();
+
+ static void * RunSendPing(void * d);
+ static void * RunRecvPing(void * d);
+
+ int delay;
+ bool nonstop;
+ bool isRunningRecver;
+ bool isRunningSender;
+ int sendSocket;
+ int recvSocket;
+ pthread_t sendThread;
+ pthread_t recvThread;
+
+ PING_MESSAGE pmSend;
+ uint32_t pid;
+
+ std::string errorStr;
+
+ std::multimap<uint32_t, time_t> pingIP;
+ std::list<uint32_t> ipToAdd;
+ std::list<uint32_t> ipToDel;
+
+ mutable pthread_mutex_t mutex;
+};
+//-----------------------------------------------------------------------------
+#endif
-#include <stdlib.h>
#include <pthread.h>
-#include <signal.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/time.h>
-#include <string.h>
#include <unistd.h>
#include <fcntl.h>
-#include <errno.h>
-#include <math.h>
-#include <stdio.h>
-#include "pinger.h"
+#include <cstdlib>
+#include <csignal>
+#include <cstring>
+#include <cerrno>
+#include <cmath>
+#include <cstdio>
+
#include "stg/common.h"
#include "stg/locker.h"
+#include "stg/pinger.h"
+
#ifdef STG_TIME
extern volatile time_t stgTime;
#endif
isRunningSender(false),
sendSocket(-1),
recvSocket(-1),
- pid(0)
+ sendThread(),
+ recvThread(),
+ pmSend(),
+ pid(0),
+ errorStr(),
+ pingIP(),
+ ipToAdd(),
+ ipToDel(),
+ mutex()
{
- pthread_mutex_init(&mutex, NULL);
- memset(&pmSend, 0, sizeof(pmSend));
+pthread_mutex_init(&mutex, NULL);
+memset(&pmSend, 0, sizeof(pmSend));
}
//-----------------------------------------------------------------------------
STG_PINGER::~STG_PINGER()
{
- pthread_mutex_destroy(&mutex);
+pthread_mutex_destroy(&mutex);
}
//-----------------------------------------------------------------------------
int STG_PINGER::Start()
{
- struct protoent *proto = NULL;
- proto = getprotobyname("ICMP");
- sendSocket = socket(PF_INET, SOCK_RAW, proto->p_proto);
- recvSocket = socket(PF_INET, SOCK_RAW, proto->p_proto);
- nonstop = true;
- pid = (int) getpid() % 65535;
- if (sendSocket < 0 || recvSocket < 0)
- {
- errorStr = "Cannot create socket.";
- return -1;
- }
+struct protoent *proto = NULL;
+proto = getprotobyname("ICMP");
+sendSocket = socket(PF_INET, SOCK_RAW, proto->p_proto);
+recvSocket = socket(PF_INET, SOCK_RAW, proto->p_proto);
+nonstop = true;
+pid = (int) getpid() % 65535;
+if (sendSocket < 0 || recvSocket < 0)
+ {
+ errorStr = "Cannot create socket.";
+ return -1;
+ }
- if (pthread_create(&sendThread, NULL, RunSendPing, this))
- {
- errorStr = "Cannot create send thread.";
- return -1;
- }
+if (pthread_create(&sendThread, NULL, RunSendPing, this))
+ {
+ errorStr = "Cannot create send thread.";
+ return -1;
+ }
- if (pthread_create(&recvThread, NULL, RunRecvPing, this))
- {
- errorStr = "Cannot create recv thread.";
- return -1;
- }
+if (pthread_create(&recvThread, NULL, RunRecvPing, this))
+ {
+ errorStr = "Cannot create recv thread.";
+ return -1;
+ }
- return 0;
+return 0;
}
//-----------------------------------------------------------------------------
int STG_PINGER::Stop()
{
- close(recvSocket);
- nonstop = false;
- if (isRunningRecver)
+close(recvSocket);
+nonstop = false;
+if (isRunningRecver)
+ {
+ //5 seconds to thread stops itself
+ for (size_t i = 0; i < 25; i++)
{
- //5 seconds to thread stops itself
- for (size_t i = 0; i < 25; i++)
- {
- if (i % 5 == 0)
- SendPing(0x0100007f);//127.0.0.1
+ if (i % 5 == 0)
+ SendPing(0x0100007f);//127.0.0.1
- if (!isRunningRecver)
- break;
+ if (!isRunningRecver)
+ break;
- usleep(200000);
- }
-
- //after 5 seconds waiting thread still running. now killing it
- if (isRunningRecver)
- {
- if (pthread_kill(recvThread, SIGINT))
- {
- errorStr = "Cannot kill thread.";
- return -1;
- }
- }
+ struct timespec ts = {0, 200000000};
+ nanosleep(&ts, NULL);
}
+ }
- if (isRunningSender)
+if (isRunningSender)
+ {
+ //5 seconds to thread stops itself
+ for (size_t i = 0; i < 25; i++)
{
- //5 seconds to thread stops itself
- for (size_t i = 0; i < 25; i++)
- {
- if (!isRunningSender)
- break;
+ if (!isRunningSender)
+ break;
- usleep(200000);
- }
-
- //after 5 seconds waiting thread still running. now killing it
- if (isRunningSender)
- {
- if (pthread_kill(sendThread, SIGINT))
- {
- errorStr = "Cannot kill thread.";
- return -1;
- }
- }
+ struct timespec ts = {0, 200000000};
+ nanosleep(&ts, NULL);
}
+ }
+
+close(sendSocket);
- close(sendSocket);
- return 0;
+if (isRunningSender || isRunningRecver)
+ return -1;
+
+return 0;
}
//-----------------------------------------------------------------------------
void STG_PINGER::AddIP(uint32_t ip)
{
- STG_LOCKER lock(&mutex, __FILE__, __LINE__);
- ipToAdd.push_back(ip);
+STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+ipToAdd.push_back(ip);
}
//-----------------------------------------------------------------------------
void STG_PINGER::DelIP(uint32_t ip)
{
- STG_LOCKER lock(&mutex, __FILE__, __LINE__);
- ipToDel.push_back(ip);
+STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+ipToDel.push_back(ip);
}
//-----------------------------------------------------------------------------
void STG_PINGER::RealAddIP()
- {
- STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+{
+STG_LOCKER lock(&mutex, __FILE__, __LINE__);
- std::list<uint32_t>::iterator iter;
- iter = ipToAdd.begin();
- while (iter != ipToAdd.end())
- {
- pingIP.insert(std::make_pair(*iter, 0));
- ++iter;
- }
- ipToAdd.erase(ipToAdd.begin(), ipToAdd.end());
+std::list<uint32_t>::iterator iter;
+iter = ipToAdd.begin();
+while (iter != ipToAdd.end())
+ {
+ pingIP.insert(std::make_pair(*iter, 0));
+ ++iter;
}
+ipToAdd.erase(ipToAdd.begin(), ipToAdd.end());
+}
//-----------------------------------------------------------------------------
void STG_PINGER::RealDelIP()
{
- STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+STG_LOCKER lock(&mutex, __FILE__, __LINE__);
- std::list<uint32_t>::iterator iter;
- std::multimap<uint32_t, time_t>::iterator treeIter;
- iter = ipToDel.begin();
- while (iter != ipToDel.end())
- {
- treeIter = pingIP.find(*iter);
- if (treeIter != pingIP.end())
- pingIP.erase(treeIter);
+std::list<uint32_t>::iterator iter;
+std::multimap<uint32_t, time_t>::iterator treeIter;
+iter = ipToDel.begin();
+while (iter != ipToDel.end())
+ {
+ treeIter = pingIP.find(*iter);
+ if (treeIter != pingIP.end())
+ pingIP.erase(treeIter);
- ++iter;
- }
- ipToDel.erase(ipToDel.begin(), ipToDel.end());
+ ++iter;
+ }
+ipToDel.erase(ipToDel.begin(), ipToDel.end());
}
//-----------------------------------------------------------------------------
int STG_PINGER::GetPingIPNum() const
{
- return pingIP.size();
+return pingIP.size();
}
//-----------------------------------------------------------------------------
void STG_PINGER::PrintAllIP()
{
- STG_LOCKER lock(&mutex, __FILE__, __LINE__);
- std::multimap<uint32_t, time_t>::iterator iter;
- iter = pingIP.begin();
- while (iter != pingIP.end())
- {
- uint32_t ip = iter->first;
- time_t t = iter->second;
- std::string s;
- x2str(t, s);
- printf("ip = %s, time = %9s\n", inet_ntostring(ip).c_str(), s.c_str());
- ++iter;
- }
+STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+std::multimap<uint32_t, time_t>::iterator iter;
+iter = pingIP.begin();
+while (iter != pingIP.end())
+ {
+ uint32_t ip = iter->first;
+ time_t t = iter->second;
+ std::string s;
+ x2str(t, s);
+ printf("ip = %s, time = %9s\n", inet_ntostring(ip).c_str(), s.c_str());
+ ++iter;
+ }
}
//-----------------------------------------------------------------------------
int STG_PINGER::GetIPTime(uint32_t ip, time_t * t) const
{
- STG_LOCKER lock(&mutex, __FILE__, __LINE__);
- std::multimap<uint32_t, time_t>::const_iterator treeIter;
+STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+std::multimap<uint32_t, time_t>::const_iterator treeIter;
- treeIter = pingIP.find(ip);
- if (treeIter == pingIP.end())
- return -1;
+treeIter = pingIP.find(ip);
+if (treeIter == pingIP.end())
+ return -1;
- *t = treeIter->second;
- return 0;
+*t = treeIter->second;
+return 0;
}
//-----------------------------------------------------------------------------
uint16_t STG_PINGER::PingCheckSum(void * data, int len)
{
- unsigned short * buf = (unsigned short *)data;
- unsigned int sum = 0;
- unsigned short result;
+unsigned short * buf = (unsigned short *)data;
+unsigned int sum = 0;
+unsigned short result;
- for ( sum = 0; len > 1; len -= 2 )
- sum += *buf++;
+for ( sum = 0; len > 1; len -= 2 )
+ sum += *buf++;
- if ( len == 1 )
- sum += *(unsigned char*)buf;
+if ( len == 1 )
+ sum += *(unsigned char*)buf;
- sum = (sum >> 16) + (sum & 0xFFFF);
- sum += (sum >> 16);
- result = ~sum;
- return result;
+sum = (sum >> 16) + (sum & 0xFFFF);
+sum += (sum >> 16);
+result = ~sum;
+return result;
}
//-----------------------------------------------------------------------------
int STG_PINGER::SendPing(uint32_t ip)
{
- struct sockaddr_in addr;
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_port = 0;
- addr.sin_addr.s_addr = ip;
+struct sockaddr_in addr;
+memset(&addr, 0, sizeof(addr));
+addr.sin_family = AF_INET;
+addr.sin_port = 0;
+addr.sin_addr.s_addr = ip;
- memset(&pmSend, 0, sizeof(pmSend));
- pmSend.hdr.type = ICMP_ECHO;
- pmSend.hdr.un.echo.id = pid;
- memcpy(pmSend.msg, &ip, sizeof(ip));
+memset(&pmSend, 0, sizeof(pmSend));
+pmSend.hdr.type = ICMP_ECHO;
+pmSend.hdr.un.echo.id = pid;
+memcpy(pmSend.msg, &ip, sizeof(ip));
- pmSend.hdr.checksum = PingCheckSum(&pmSend, sizeof(pmSend));
+pmSend.hdr.checksum = PingCheckSum(&pmSend, sizeof(pmSend));
- if (sendto(sendSocket, &pmSend, sizeof(pmSend), 0, (sockaddr *)&addr, sizeof(addr)) <= 0 )
- {
- errorStr = "Send ping error: " + std::string(strerror(errno));
- return -1;
- }
+if (sendto(sendSocket, &pmSend, sizeof(pmSend), 0, (sockaddr *)&addr, sizeof(addr)) <= 0 )
+ {
+ errorStr = "Send ping error: " + std::string(strerror(errno));
+ return -1;
+ }
- return 0;
+return 0;
}
//-----------------------------------------------------------------------------
uint32_t STG_PINGER::RecvPing()
{
- struct sockaddr_in addr;
- uint32_t ipAddr = 0;
+struct sockaddr_in addr;
+uint32_t ipAddr = 0;
- char buf[128];
- memset(buf, 0, sizeof(buf));
- int bytes;
- socklen_t len = sizeof(addr);
+char buf[128];
+memset(buf, 0, sizeof(buf));
+int bytes;
+socklen_t len = sizeof(addr);
- bytes = recvfrom(recvSocket, &buf, sizeof(buf), 0, (struct sockaddr*)&addr, &len);
- if (bytes > 0)
- {
- struct IP_HDR * ip = (struct IP_HDR *)buf;
- struct ICMP_HDR *icmp = (struct ICMP_HDR *)(buf + ip->ihl * 4);
+bytes = recvfrom(recvSocket, &buf, sizeof(buf), 0, (struct sockaddr*)&addr, &len);
+if (bytes > 0)
+ {
+ struct IP_HDR * ip = (struct IP_HDR *)buf;
+ struct ICMP_HDR *icmp = (struct ICMP_HDR *)(buf + ip->ihl * 4);
- if (icmp->un.echo.id != pid)
- return 0;
+ if (icmp->un.echo.id != pid)
+ return 0;
- ipAddr = *(uint32_t*)(buf + sizeof(ICMP_HDR) + ip->ihl * 4);
- }
+ ipAddr = *(uint32_t*)(buf + sizeof(ICMP_HDR) + ip->ihl * 4);
+ }
- return ipAddr;
+return ipAddr;
}
//-----------------------------------------------------------------------------
void * STG_PINGER::RunSendPing(void * d)
{
- STG_PINGER * pinger = static_cast<STG_PINGER *>(d);
+sigset_t signalSet;
+sigfillset(&signalSet);
+pthread_sigmask(SIG_BLOCK, &signalSet, NULL);
+
+STG_PINGER * pinger = static_cast<STG_PINGER *>(d);
- pinger->isRunningSender = true;
- time_t lastPing = 0;
- while (pinger->nonstop)
+pinger->isRunningSender = true;
+time_t lastPing = 0;
+while (pinger->nonstop)
+ {
+ pinger->RealAddIP();
+ pinger->RealDelIP();
+
+ std::multimap<uint32_t, time_t>::iterator iter;
+ iter = pinger->pingIP.begin();
+ while (iter != pinger->pingIP.end())
{
- pinger->RealAddIP();
- pinger->RealDelIP();
+ pinger->SendPing(iter->first);
+ ++iter;
+ }
- std::multimap<uint32_t, time_t>::iterator iter;
- iter = pinger->pingIP.begin();
- while (iter != pinger->pingIP.end())
- {
- pinger->SendPing(iter->first);
- ++iter;
- }
+ time_t currTime;
- time_t currTime;
+ #ifdef STG_TIME
+ lastPing = stgTime;
+ currTime = stgTime;
+ #else
+ currTime = lastPing = time(NULL);
+ #endif
+ while (currTime - lastPing < pinger->delay && pinger->nonstop)
+ {
#ifdef STG_TIME
- lastPing = stgTime;
currTime = stgTime;
#else
- currTime = lastPing = time(NULL);
+ currTime = time(NULL);
#endif
-
- while (currTime - lastPing < pinger->delay && pinger->nonstop)
- {
- #ifdef STG_TIME
- currTime = stgTime;
- #else
- currTime = time(NULL);
- #endif
- usleep(20000);
- }
+ struct timespec ts = {0, 20000000};
+ nanosleep(&ts, NULL);
}
+ }
- pinger->isRunningSender = false;
+pinger->isRunningSender = false;
- return NULL;
+return NULL;
}
//-----------------------------------------------------------------------------
void * STG_PINGER::RunRecvPing(void * d)
{
- STG_PINGER * pinger = static_cast<STG_PINGER *>(d);
+sigset_t signalSet;
+sigfillset(&signalSet);
+pthread_sigmask(SIG_BLOCK, &signalSet, NULL);
- pinger->isRunningRecver = true;
+STG_PINGER * pinger = static_cast<STG_PINGER *>(d);
- while (pinger->nonstop)
- {
- uint32_t ip = pinger->RecvPing();
+pinger->isRunningRecver = true;
+
+while (pinger->nonstop)
+ {
+ uint32_t ip = pinger->RecvPing();
- if (ip)
+ if (ip)
+ {
+ std::multimap<uint32_t, time_t>::iterator treeIterUpper = pinger->pingIP.upper_bound(ip);
+ std::multimap<uint32_t, time_t>::iterator treeIterLower = pinger->pingIP.lower_bound(ip);
+ while (treeIterUpper != treeIterLower)
{
- std::multimap<uint32_t, time_t>::iterator treeIterUpper = pinger->pingIP.upper_bound(ip);
- std::multimap<uint32_t, time_t>::iterator treeIterLower = pinger->pingIP.lower_bound(ip);
- while (treeIterUpper != treeIterLower)
- {
- #ifdef STG_TIME
- treeIterLower->second = stgTime;
- #else
- treeIterLower->second = time(NULL);
- #endif
- ++treeIterLower;
- }
+ #ifdef STG_TIME
+ treeIterLower->second = stgTime;
+ #else
+ treeIterLower->second = time(NULL);
+ #endif
+ ++treeIterLower;
}
-
}
- pinger->isRunningRecver = false;
- return NULL;
+
+ }
+pinger->isRunningRecver = false;
+return NULL;
}
//-----------------------------------------------------------------------------
+++ /dev/null
- /*
- $Revision: 1.8 $
- $Date: 2008/05/10 11:59:53 $
- $Author: nobunaga $
- */
-
-#ifndef PINGER_H
-#define PINGER_H
-
-#include <ctime>
-#include <string>
-#include <list>
-#include <map>
-
-#ifdef LINUX
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/ip_icmp.h>
-#endif
-
-#if defined (FREE_BSD) || defined (FREE_BSD5)
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#include <netinet/ip_icmp.h>
-#include <netinet/ip_var.h>
-#include <arpa/inet.h>
-#endif
-
-#include "stg/os_int.h"
-
-//-----------------------------------------------------------------------------
-struct ICMP_HDR
-{
-uint8_t type;
-uint8_t code;
-uint16_t checksum;
-union
- {
- struct
- {
- uint16_t id;
- uint16_t sequence;
- } echo;
- uint32_t gateway;
- struct
- {
- uint16_t unused;
- uint16_t mtu;
- } frag;
- } un;
-};
-//-----------------------------------------------------------------------------
-struct IP_HDR
-{
- uint8_t ihl:4,
- version:4;
- uint8_t tos;
- uint16_t tot_len;
- uint16_t id;
- uint16_t frag_off;
- uint8_t ttl;
- uint8_t protocol;
- uint16_t check;
- uint32_t saddr;
- uint32_t daddr;
-};
-//-----------------------------------------------------------------------------
-struct PING_IP_TIME
-{
-uint32_t ip;
-time_t pingTime;
-};
-//-----------------------------------------------------------------------------
-
-#define PING_DATA_LEN (64)
-//-----------------------------------------------------------------------------
-struct PING_MESSAGE
-{
- ICMP_HDR hdr;
- char msg[PING_DATA_LEN];
-};
-//-----------------------------------------------------------------------------
-class STG_PINGER
-{
-public:
- STG_PINGER(time_t delay = 15);
- ~STG_PINGER();
-
- int Start();
- int Stop();
- void AddIP(uint32_t ip);
- void DelIP(uint32_t ip);
- int GetPingIPNum() const;
- void PrintAllIP();
- int GetIPTime(uint32_t ip, time_t * t) const;
- void SetDelayTime(time_t d) { delay = d; }
- time_t GetDelayTime() const { return delay; }
- const std::string & GetStrError() const { return errorStr; }
-
-private:
- uint16_t PingCheckSum(void * data, int len);
- int SendPing(uint32_t ip);
- uint32_t RecvPing();
- void RealAddIP();
- void RealDelIP();
-
- static void * RunSendPing(void * d);
- static void * RunRecvPing(void * d);
-
- int delay;
- bool nonstop;
- bool isRunningRecver;
- bool isRunningSender;
- int sendSocket;
- int recvSocket;
- pthread_t sendThread;
- pthread_t recvThread;
-
- PING_MESSAGE pmSend;
- uint32_t pid;
-
- std::string errorStr;
-
- std::multimap<uint32_t, time_t> pingIP;
- std::list<uint32_t> ipToAdd;
- std::list<uint32_t> ipToDel;
-
- mutable pthread_mutex_t mutex;
-};
-//-----------------------------------------------------------------------------
-#endif
LIB_NAME = stgscriptexecuter
-SRCS = scriptexecuter.cpp
+SRCS = scriptexecuter.c
INCS = scriptexecuter.h
--- /dev/null
+#ifndef SCRIPT_EXECUTER_H
+#define SCRIPT_EXECUTER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int ScriptExec(const char * str);
+#ifdef LINUX
+void Executer(int msgID, pid_t pid, char * procName);
+#else
+void Executer(int msgID, pid_t pid);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/msg.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <signal.h>
+
+#include "stg/scriptexecuter.h"
+
+#define MAX_SCRIPT_LEN (1100)
+
+static int msgid;
+static int nonstop;
+
+//-----------------------------------------------------------------------------
+struct SCRIPT_DATA
+{
+ long mtype;
+ char script[MAX_SCRIPT_LEN];
+} sd;
+//-----------------------------------------------------------------------------
+static void CatchUSR1Executer()
+{
+nonstop = 0;
+}
+//-----------------------------------------------------------------------------
+int ScriptExec(const char * str)
+{
+if (strlen(str) >= MAX_SCRIPT_LEN)
+ return -1;
+
+strncpy(sd.script, str, MAX_SCRIPT_LEN);
+sd.mtype = 1;
+if (msgsnd(msgid, (void *)&sd, MAX_SCRIPT_LEN, 0) < 0)
+ return -1;
+
+return 0;
+}
+//-----------------------------------------------------------------------------
+#ifdef LINUX
+void Executer(int msgID, pid_t pid, char * procName)
+#else
+void Executer(int msgID, pid_t pid)
+#endif
+{
+int ret;
+struct SCRIPT_DATA sd;
+struct sigaction newsa, oldsa;
+sigset_t sigmask;
+
+msgid = msgID;
+if (pid)
+ return;
+nonstop = 1;
+
+#ifdef LINUX
+memset(procName, 0, strlen(procName));
+strcpy(procName, "stg-exec");
+#else
+setproctitle("stg-exec");
+#endif
+
+sigemptyset(&sigmask);
+sigaddset(&sigmask, SIGTERM);
+newsa.sa_handler = SIG_IGN;
+newsa.sa_mask = sigmask;
+newsa.sa_flags = 0;
+sigaction(SIGTERM, &newsa, &oldsa);
+
+sigemptyset(&sigmask);
+sigaddset(&sigmask, SIGINT);
+newsa.sa_handler = SIG_IGN;
+newsa.sa_mask = sigmask;
+newsa.sa_flags = 0;
+sigaction(SIGINT, &newsa, &oldsa);
+
+sigemptyset(&sigmask);
+sigaddset(&sigmask, SIGHUP);
+newsa.sa_handler = SIG_IGN;
+newsa.sa_mask = sigmask;
+newsa.sa_flags = 0;
+sigaction(SIGHUP, &newsa, &oldsa);
+
+sigemptyset(&sigmask);
+sigaddset(&sigmask, SIGUSR1);
+newsa.sa_handler = CatchUSR1Executer;
+newsa.sa_mask = sigmask;
+newsa.sa_flags = 0;
+sigaction(SIGUSR1, &newsa, &oldsa);
+
+while (nonstop)
+ {
+ sd.mtype = 1;
+ ret = msgrcv(msgid, &sd, MAX_SCRIPT_LEN, 0, 0);
+
+ if (ret < 0)
+ {
+ usleep(20000);
+ continue;
+ }
+ ret = system(sd.script);
+ if (ret == -1)
+ {
+ // Fork failed
+ }
+ }
+}
+//-----------------------------------------------------------------------------
+++ /dev/null
-#include <sys/types.h>
-#include <sys/ipc.h>
-#include <sys/msg.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include <cstring>
-#include <cerrno>
-#include <csignal>
-
-#include "stg/common.h"
-#include "scriptexecuter.h"
-
-using namespace std;
-
-#define MAX_SCRIPT_LEN (1100)
-
-static int msgid;
-static bool nonstop;
-
-//-----------------------------------------------------------------------------
-struct SCRIPT_DATA
-{
- long mtype;
- char script[MAX_SCRIPT_LEN];
-} sd;
-//-----------------------------------------------------------------------------
-static void CatchUSR1Executer(int)
-{
-nonstop = false;
-}
-//-----------------------------------------------------------------------------
-int ScriptExec(const string & str)
-{
-if (str.length() >= MAX_SCRIPT_LEN)
- {
- printfd(__FILE__, "ScriptExec() - script params exceeds MAX_SCRIPT_LENGTH (%d > %d)\n", str.length(), MAX_SCRIPT_LEN);
- return -1;
- }
-
-strncpy(sd.script, str.c_str(), MAX_SCRIPT_LEN);
-sd.mtype = 1;
-if (msgsnd(msgid, (void *)&sd, MAX_SCRIPT_LEN, 0) < 0)
- {
- printfd(__FILE__, "ScriptExec() - failed to send message to the IPC queue: '%s'\n", strerror(errno));
- return -1;
- }
-return 0;
-}
-//-----------------------------------------------------------------------------
-#ifdef LINUX
-void Executer(int, int msgID, pid_t pid, char * procName)
-#else
-void Executer(int, int msgID, pid_t pid, char *)
-#endif
-{
-msgid = msgID;
-if (pid)
- return;
-nonstop = true;
-
-#ifdef LINUX
-memset(procName, 0, strlen(procName));
-strcpy(procName, "stg-exec");
-#else
-setproctitle("stg-exec");
-#endif
-
-struct sigaction newsa, oldsa;
-sigset_t sigmask;
-
-sigemptyset(&sigmask);
-sigaddset(&sigmask, SIGTERM);
-newsa.sa_handler = SIG_IGN;
-newsa.sa_mask = sigmask;
-newsa.sa_flags = 0;
-sigaction(SIGTERM, &newsa, &oldsa);
-
-sigemptyset(&sigmask);
-sigaddset(&sigmask, SIGINT);
-newsa.sa_handler = SIG_IGN;
-newsa.sa_mask = sigmask;
-newsa.sa_flags = 0;
-sigaction(SIGINT, &newsa, &oldsa);
-
-sigemptyset(&sigmask);
-sigaddset(&sigmask, SIGHUP);
-newsa.sa_handler = SIG_IGN;
-newsa.sa_mask = sigmask;
-newsa.sa_flags = 0;
-sigaction(SIGHUP, &newsa, &oldsa);
-
-sigemptyset(&sigmask);
-sigaddset(&sigmask, SIGUSR1);
-newsa.sa_handler = CatchUSR1Executer;
-newsa.sa_mask = sigmask;
-newsa.sa_flags = 0;
-sigaction(SIGUSR1, &newsa, &oldsa);
-
-int ret;
-
-SCRIPT_DATA sd;
-
-while (nonstop)
- {
- sd.mtype = 1;
- ret = msgrcv(msgid, &sd, MAX_SCRIPT_LEN, 0, 0);
-
- if (ret < 0)
- {
- usleep(20000);
- continue;
- }
- int ret = system(sd.script);
- if (ret == -1)
- {
- // Fork failed
- }
- }
-}
-//-----------------------------------------------------------------------------
+++ /dev/null
-#ifndef SCRIPT_EXECUTER_H
-#define SCRIPT_EXECUTER_H
-
-#include <string>
-
-int ScriptExec(const std::string & str);
-void Executer(int msgKey, int msgID, pid_t pid, char * procName);
-
-#endif //SCRIPT_EXECUTER_H
--- /dev/null
+/*-
+ * Copyright (c) 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#include <asn_internal.h>
+#include <ANY.h>
+#include <errno.h>
+
+static asn_OCTET_STRING_specifics_t asn_DEF_ANY_specs = {
+ sizeof(ANY_t),
+ offsetof(ANY_t, _asn_ctx),
+ 2 /* Special indicator that this is an ANY type */
+};
+asn_TYPE_descriptor_t asn_DEF_ANY = {
+ "ANY",
+ "ANY",
+ OCTET_STRING_free,
+ OCTET_STRING_print,
+ asn_generic_no_constraint,
+ OCTET_STRING_decode_ber,
+ OCTET_STRING_encode_der,
+ OCTET_STRING_decode_xer_hex,
+ ANY_encode_xer,
+ 0, 0,
+ 0, /* Use generic outmost tag fetcher */
+ 0, 0, 0, 0,
+ 0, /* No PER visible constraints */
+ 0, 0, /* No members */
+ &asn_DEF_ANY_specs,
+};
+
+
+asn_enc_rval_t
+ANY_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+
+ if(flags & XER_F_CANONICAL) {
+ /*
+ * Canonical XER-encoding of ANY type is not supported.
+ */
+ _ASN_ENCODE_FAILED;
+ }
+
+ /* Dump as binary */
+ return OCTET_STRING_encode_xer(td, sptr, ilevel, flags, cb, app_key);
+}
+
+struct _callback_arg {
+ uint8_t *buffer;
+ size_t offset;
+ size_t size;
+};
+
+static int ANY__consume_bytes(const void *buffer, size_t size, void *key);
+
+int
+ANY_fromType(ANY_t *st, asn_TYPE_descriptor_t *td, void *sptr) {
+ struct _callback_arg arg;
+ asn_enc_rval_t erval;
+
+ if(!st || !td) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if(!sptr) {
+ if(st->buf) FREEMEM(st->buf);
+ st->size = 0;
+ return 0;
+ }
+
+ arg.offset = arg.size = 0;
+ arg.buffer = 0;
+
+ erval = der_encode(td, sptr, ANY__consume_bytes, &arg);
+ if(erval.encoded == -1) {
+ if(arg.buffer) FREEMEM(arg.buffer);
+ return -1;
+ }
+ assert((size_t)erval.encoded == arg.offset);
+
+ if(st->buf) FREEMEM(st->buf);
+ st->buf = arg.buffer;
+ st->size = arg.offset;
+
+ return 0;
+}
+
+ANY_t *
+ANY_new_fromType(asn_TYPE_descriptor_t *td, void *sptr) {
+ ANY_t tmp;
+ ANY_t *st;
+
+ if(!td || !sptr) {
+ errno = EINVAL;
+ return 0;
+ }
+
+ memset(&tmp, 0, sizeof(tmp));
+
+ if(ANY_fromType(&tmp, td, sptr)) return 0;
+
+ st = (ANY_t *)CALLOC(1, sizeof(ANY_t));
+ if(st) {
+ *st = tmp;
+ return st;
+ } else {
+ FREEMEM(tmp.buf);
+ return 0;
+ }
+}
+
+int
+ANY_to_type(ANY_t *st, asn_TYPE_descriptor_t *td, void **struct_ptr) {
+ asn_dec_rval_t rval;
+ void *newst = 0;
+
+ if(!st || !td || !struct_ptr) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if(st->buf == 0) {
+ /* Nothing to convert, make it empty. */
+ *struct_ptr = (void *)0;
+ return 0;
+ }
+
+ rval = ber_decode(0, td, (void **)&newst, st->buf, st->size);
+ if(rval.code == RC_OK) {
+ *struct_ptr = newst;
+ return 0;
+ } else {
+ /* Remove possibly partially decoded data. */
+ ASN_STRUCT_FREE(*td, newst);
+ return -1;
+ }
+}
+
+static int ANY__consume_bytes(const void *buffer, size_t size, void *key) {
+ struct _callback_arg *arg = (struct _callback_arg *)key;
+
+ if((arg->offset + size) >= arg->size) {
+ size_t nsize = (arg->size ? arg->size << 2 : 16) + size;
+ void *p = REALLOC(arg->buffer, nsize);
+ if(!p) return -1;
+ arg->buffer = (uint8_t *)p;
+ arg->size = nsize;
+ }
+
+ memcpy(arg->buffer + arg->offset, buffer, size);
+ arg->offset += size;
+ assert(arg->offset < arg->size);
+
+ return 0;
+}
+
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1155-SMI"
+ * found in "RFC1155-SMI.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#include <asn_internal.h>
+
+#include "ApplicationSyntax.h"
+
+static asn_TYPE_member_t asn_MBR_ApplicationSyntax_1[] = {
+ { ATF_NOFLAGS, 0, offsetof(struct ApplicationSyntax, choice.address),
+ -1 /* Ambiguous tag (CHOICE?) */,
+ 0,
+ &asn_DEF_NetworkAddress,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "address"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct ApplicationSyntax, choice.counter),
+ (ASN_TAG_CLASS_APPLICATION | (1 << 2)),
+ 0,
+ &asn_DEF_Counter,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "counter"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct ApplicationSyntax, choice.gauge),
+ (ASN_TAG_CLASS_APPLICATION | (2 << 2)),
+ 0,
+ &asn_DEF_Gauge,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "gauge"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct ApplicationSyntax, choice.ticks),
+ (ASN_TAG_CLASS_APPLICATION | (3 << 2)),
+ 0,
+ &asn_DEF_TimeTicks,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "ticks"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct ApplicationSyntax, choice.arbitrary),
+ (ASN_TAG_CLASS_APPLICATION | (4 << 2)),
+ 0,
+ &asn_DEF_Opaque,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "arbitrary"
+ },
+};
+static asn_TYPE_tag2member_t asn_MAP_ApplicationSyntax_tag2el_1[] = {
+ { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 0, 0, 0 }, /* internet at 113 */
+ { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 1, 0, 0 }, /* counter at 91 */
+ { (ASN_TAG_CLASS_APPLICATION | (2 << 2)), 2, 0, 0 }, /* gauge at 94 */
+ { (ASN_TAG_CLASS_APPLICATION | (3 << 2)), 3, 0, 0 }, /* ticks at 97 */
+ { (ASN_TAG_CLASS_APPLICATION | (4 << 2)), 4, 0, 0 } /* arbitrary at 104 */
+};
+static asn_CHOICE_specifics_t asn_SPC_ApplicationSyntax_specs_1 = {
+ sizeof(struct ApplicationSyntax),
+ offsetof(struct ApplicationSyntax, _asn_ctx),
+ offsetof(struct ApplicationSyntax, present),
+ sizeof(((struct ApplicationSyntax *)0)->present),
+ asn_MAP_ApplicationSyntax_tag2el_1,
+ 5, /* Count of tags in the map */
+ 0,
+ -1 /* Extensions start */
+};
+asn_TYPE_descriptor_t asn_DEF_ApplicationSyntax = {
+ "ApplicationSyntax",
+ "ApplicationSyntax",
+ CHOICE_free,
+ CHOICE_print,
+ CHOICE_constraint,
+ CHOICE_decode_ber,
+ CHOICE_encode_der,
+ CHOICE_decode_xer,
+ CHOICE_encode_xer,
+ 0, 0, /* No PER support, use "-gen-PER" to enable */
+ CHOICE_outmost_tag,
+ 0, /* No effective tags (pointer) */
+ 0, /* No effective tags (count) */
+ 0, /* No tags (pointer) */
+ 0, /* No tags (count) */
+ 0, /* No PER visible constraints */
+ asn_MBR_ApplicationSyntax_1,
+ 5, /* Elements count */
+ &asn_SPC_ApplicationSyntax_specs_1 /* Additional specs */
+};
+
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1213-MIB"
+ * found in "RFC1213-MIB.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#include <asn_internal.h>
+
+#include "AtEntry.h"
+
+static asn_TYPE_member_t asn_MBR_AtEntry_1[] = {
+ { ATF_NOFLAGS, 0, offsetof(struct AtEntry, atIfIndex),
+ (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
+ 0,
+ &asn_DEF_INTEGER,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "atIfIndex"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct AtEntry, atPhysAddress),
+ (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)),
+ 0,
+ &asn_DEF_PhysAddress,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "atPhysAddress"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct AtEntry, atNetAddress),
+ -1 /* Ambiguous tag (CHOICE?) */,
+ 0,
+ &asn_DEF_NetworkAddress,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "atNetAddress"
+ },
+};
+static ber_tlv_tag_t asn_DEF_AtEntry_tags_1[] = {
+ (ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
+};
+static asn_TYPE_tag2member_t asn_MAP_AtEntry_tag2el_1[] = {
+ { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 0 }, /* atIfIndex at 154 */
+ { (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 1, 0, 0 }, /* atPhysAddress at 157 */
+ { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 2, 0, 0 } /* internet at 113 */
+};
+static asn_SEQUENCE_specifics_t asn_SPC_AtEntry_specs_1 = {
+ sizeof(struct AtEntry),
+ offsetof(struct AtEntry, _asn_ctx),
+ asn_MAP_AtEntry_tag2el_1,
+ 3, /* Count of tags in the map */
+ 0, 0, 0, /* Optional elements (not needed) */
+ -1, /* Start extensions */
+ -1 /* Stop extensions */
+};
+asn_TYPE_descriptor_t asn_DEF_AtEntry = {
+ "AtEntry",
+ "AtEntry",
+ SEQUENCE_free,
+ SEQUENCE_print,
+ SEQUENCE_constraint,
+ SEQUENCE_decode_ber,
+ SEQUENCE_encode_der,
+ SEQUENCE_decode_xer,
+ SEQUENCE_encode_xer,
+ 0, 0, /* No PER support, use "-gen-PER" to enable */
+ 0, /* Use generic outmost tag fetcher */
+ asn_DEF_AtEntry_tags_1,
+ sizeof(asn_DEF_AtEntry_tags_1)
+ /sizeof(asn_DEF_AtEntry_tags_1[0]), /* 1 */
+ asn_DEF_AtEntry_tags_1, /* Same as above */
+ sizeof(asn_DEF_AtEntry_tags_1)
+ /sizeof(asn_DEF_AtEntry_tags_1[0]), /* 1 */
+ 0, /* No PER visible constraints */
+ asn_MBR_AtEntry_1,
+ 3, /* Elements count */
+ &asn_SPC_AtEntry_specs_1 /* Additional specs */
+};
+
--- /dev/null
+/*-
+ * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#include <asn_internal.h>
+#include <BIT_STRING.h>
+#include <asn_internal.h>
+
+/*
+ * BIT STRING basic type description.
+ */
+static ber_tlv_tag_t asn_DEF_BIT_STRING_tags[] = {
+ (ASN_TAG_CLASS_UNIVERSAL | (3 << 2))
+};
+static asn_OCTET_STRING_specifics_t asn_DEF_BIT_STRING_specs = {
+ sizeof(BIT_STRING_t),
+ offsetof(BIT_STRING_t, _asn_ctx),
+ 1, /* Special indicator that this is a BIT STRING type */
+};
+asn_TYPE_descriptor_t asn_DEF_BIT_STRING = {
+ "BIT STRING",
+ "BIT_STRING",
+ OCTET_STRING_free, /* Implemented in terms of OCTET STRING */
+ BIT_STRING_print,
+ BIT_STRING_constraint,
+ OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */
+ OCTET_STRING_encode_der, /* Implemented in terms of OCTET STRING */
+ OCTET_STRING_decode_xer_binary,
+ BIT_STRING_encode_xer,
+ OCTET_STRING_decode_uper, /* Unaligned PER decoder */
+ OCTET_STRING_encode_uper, /* Unaligned PER encoder */
+ 0, /* Use generic outmost tag fetcher */
+ asn_DEF_BIT_STRING_tags,
+ sizeof(asn_DEF_BIT_STRING_tags)
+ / sizeof(asn_DEF_BIT_STRING_tags[0]),
+ asn_DEF_BIT_STRING_tags, /* Same as above */
+ sizeof(asn_DEF_BIT_STRING_tags)
+ / sizeof(asn_DEF_BIT_STRING_tags[0]),
+ 0, /* No PER visible constraints */
+ 0, 0, /* No members */
+ &asn_DEF_BIT_STRING_specs
+};
+
+/*
+ * BIT STRING generic constraint.
+ */
+int
+BIT_STRING_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
+ asn_app_constraint_failed_f *ctfailcb, void *app_key) {
+ const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;
+
+ if(st && st->buf) {
+ if(st->size == 1 && st->bits_unused) {
+ _ASN_CTFAIL(app_key, td,
+ "%s: invalid padding byte (%s:%d)",
+ td->name, __FILE__, __LINE__);
+ return -1;
+ }
+ } else {
+ _ASN_CTFAIL(app_key, td,
+ "%s: value not given (%s:%d)",
+ td->name, __FILE__, __LINE__);
+ return -1;
+ }
+
+ return 0;
+}
+
+static char *_bit_pattern[16] = {
+ "0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111",
+ "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"
+};
+
+asn_enc_rval_t
+BIT_STRING_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ asn_enc_rval_t er;
+ char scratch[128];
+ char *p = scratch;
+ char *scend = scratch + (sizeof(scratch) - 10);
+ const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;
+ int xcan = (flags & XER_F_CANONICAL);
+ uint8_t *buf;
+ uint8_t *end;
+
+ if(!st || !st->buf)
+ _ASN_ENCODE_FAILED;
+
+ er.encoded = 0;
+
+ buf = st->buf;
+ end = buf + st->size - 1; /* Last byte is special */
+
+ /*
+ * Binary dump
+ */
+ for(; buf < end; buf++) {
+ int v = *buf;
+ int nline = xcan?0:(((buf - st->buf) % 8) == 0);
+ if(p >= scend || nline) {
+ er.encoded += p - scratch;
+ _ASN_CALLBACK(scratch, p - scratch);
+ p = scratch;
+ if(nline) _i_ASN_TEXT_INDENT(1, ilevel);
+ }
+ memcpy(p + 0, _bit_pattern[v >> 4], 4);
+ memcpy(p + 4, _bit_pattern[v & 0x0f], 4);
+ p += 8;
+ }
+
+ if(!xcan && ((buf - st->buf) % 8) == 0)
+ _i_ASN_TEXT_INDENT(1, ilevel);
+ er.encoded += p - scratch;
+ _ASN_CALLBACK(scratch, p - scratch);
+ p = scratch;
+
+ if(buf == end) {
+ int v = *buf;
+ int ubits = st->bits_unused;
+ int i;
+ for(i = 7; i >= ubits; i--)
+ *p++ = (v & (1 << i)) ? 0x31 : 0x30;
+ er.encoded += p - scratch;
+ _ASN_CALLBACK(scratch, p - scratch);
+ }
+
+ if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel - 1);
+
+ _ASN_ENCODED_OK(er);
+cb_failed:
+ _ASN_ENCODE_FAILED;
+}
+
+
+/*
+ * BIT STRING specific contents printer.
+ */
+int
+BIT_STRING_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ static const char *h2c = "0123456789ABCDEF";
+ char scratch[64];
+ const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;
+ uint8_t *buf;
+ uint8_t *end;
+ char *p = scratch;
+
+ (void)td; /* Unused argument */
+
+ if(!st || !st->buf)
+ return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
+
+ ilevel++;
+ buf = st->buf;
+ end = buf + st->size;
+
+ /*
+ * Hexadecimal dump.
+ */
+ for(; buf < end; buf++) {
+ if((buf - st->buf) % 16 == 0 && (st->size > 16)
+ && buf != st->buf) {
+ _i_INDENT(1);
+ /* Dump the string */
+ if(cb(scratch, p - scratch, app_key) < 0) return -1;
+ p = scratch;
+ }
+ *p++ = h2c[*buf >> 4];
+ *p++ = h2c[*buf & 0x0F];
+ *p++ = 0x20;
+ }
+
+ if(p > scratch) {
+ p--; /* Eat the tailing space */
+
+ if((st->size > 16)) {
+ _i_INDENT(1);
+ }
+
+ /* Dump the incomplete 16-bytes row */
+ if(cb(scratch, p - scratch, app_key) < 0)
+ return -1;
+ }
+
+ return 0;
+}
+
--- /dev/null
+/*-
+ * Copyright (c) 2003, 2005 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#include <asn_internal.h>
+#include <asn_codecs_prim.h>
+#include <BOOLEAN.h>
+
+/*
+ * BOOLEAN basic type description.
+ */
+static ber_tlv_tag_t asn_DEF_BOOLEAN_tags[] = {
+ (ASN_TAG_CLASS_UNIVERSAL | (1 << 2))
+};
+asn_TYPE_descriptor_t asn_DEF_BOOLEAN = {
+ "BOOLEAN",
+ "BOOLEAN",
+ BOOLEAN_free,
+ BOOLEAN_print,
+ asn_generic_no_constraint,
+ BOOLEAN_decode_ber,
+ BOOLEAN_encode_der,
+ BOOLEAN_decode_xer,
+ BOOLEAN_encode_xer,
+ BOOLEAN_decode_uper, /* Unaligned PER decoder */
+ BOOLEAN_encode_uper, /* Unaligned PER encoder */
+ 0, /* Use generic outmost tag fetcher */
+ asn_DEF_BOOLEAN_tags,
+ sizeof(asn_DEF_BOOLEAN_tags) / sizeof(asn_DEF_BOOLEAN_tags[0]),
+ asn_DEF_BOOLEAN_tags, /* Same as above */
+ sizeof(asn_DEF_BOOLEAN_tags) / sizeof(asn_DEF_BOOLEAN_tags[0]),
+ 0, /* No PER visible constraints */
+ 0, 0, /* No members */
+ 0 /* No specifics */
+};
+
+/*
+ * Decode BOOLEAN type.
+ */
+asn_dec_rval_t
+BOOLEAN_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
+ asn_TYPE_descriptor_t *td,
+ void **bool_value, const void *buf_ptr, size_t size,
+ int tag_mode) {
+ BOOLEAN_t *st = (BOOLEAN_t *)*bool_value;
+ asn_dec_rval_t rval;
+ ber_tlv_len_t length;
+ ber_tlv_len_t lidx;
+
+ if(st == NULL) {
+ st = (BOOLEAN_t *)(*bool_value = CALLOC(1, sizeof(*st)));
+ if(st == NULL) {
+ rval.code = RC_FAIL;
+ rval.consumed = 0;
+ return rval;
+ }
+ }
+
+ ASN_DEBUG("Decoding %s as BOOLEAN (tm=%d)",
+ td->name, tag_mode);
+
+ /*
+ * Check tags.
+ */
+ rval = ber_check_tags(opt_codec_ctx, td, 0, buf_ptr, size,
+ tag_mode, 0, &length, 0);
+ if(rval.code != RC_OK)
+ return rval;
+
+ ASN_DEBUG("Boolean length is %d bytes", (int)length);
+
+ buf_ptr = ((const char *)buf_ptr) + rval.consumed;
+ size -= rval.consumed;
+ if(length > (ber_tlv_len_t)size) {
+ rval.code = RC_WMORE;
+ rval.consumed = 0;
+ return rval;
+ }
+
+ /*
+ * Compute boolean value.
+ */
+ for(*st = 0, lidx = 0;
+ (lidx < length) && *st == 0; lidx++) {
+ /*
+ * Very simple approach: read bytes until the end or
+ * value is already TRUE.
+ * BOOLEAN is not supposed to contain meaningful data anyway.
+ */
+ *st |= ((const uint8_t *)buf_ptr)[lidx];
+ }
+
+ rval.code = RC_OK;
+ rval.consumed += length;
+
+ ASN_DEBUG("Took %ld/%ld bytes to encode %s, value=%d",
+ (long)rval.consumed, (long)length,
+ td->name, *st);
+
+ return rval;
+}
+
+asn_enc_rval_t
+BOOLEAN_encode_der(asn_TYPE_descriptor_t *td, void *sptr,
+ int tag_mode, ber_tlv_tag_t tag,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ asn_enc_rval_t erval;
+ BOOLEAN_t *st = (BOOLEAN_t *)sptr;
+
+ erval.encoded = der_write_tags(td, 1, tag_mode, 0, tag, cb, app_key);
+ if(erval.encoded == -1) {
+ erval.failed_type = td;
+ erval.structure_ptr = sptr;
+ return erval;
+ }
+
+ if(cb) {
+ uint8_t bool_value;
+
+ bool_value = *st ? 0xff : 0; /* 0xff mandated by DER */
+
+ if(cb(&bool_value, 1, app_key) < 0) {
+ erval.encoded = -1;
+ erval.failed_type = td;
+ erval.structure_ptr = sptr;
+ return erval;
+ }
+ }
+
+ erval.encoded += 1;
+
+ _ASN_ENCODED_OK(erval);
+}
+
+
+/*
+ * Decode the chunk of XML text encoding INTEGER.
+ */
+static enum xer_pbd_rval
+BOOLEAN__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chunk_buf, size_t chunk_size) {
+ BOOLEAN_t *st = (BOOLEAN_t *)sptr;
+ const char *p = (const char *)chunk_buf;
+
+ (void)td;
+
+ if(chunk_size && p[0] == 0x3c /* '<' */) {
+ switch(xer_check_tag(chunk_buf, chunk_size, "false")) {
+ case XCT_BOTH:
+ /* "<false/>" */
+ *st = 0;
+ break;
+ case XCT_UNKNOWN_BO:
+ if(xer_check_tag(chunk_buf, chunk_size, "true")
+ != XCT_BOTH)
+ return XPBD_BROKEN_ENCODING;
+ /* "<true/>" */
+ *st = 1; /* Or 0xff as in DER?.. */
+ break;
+ default:
+ return XPBD_BROKEN_ENCODING;
+ }
+ return XPBD_BODY_CONSUMED;
+ } else {
+ if(xer_is_whitespace(chunk_buf, chunk_size))
+ return XPBD_NOT_BODY_IGNORE;
+ else
+ return XPBD_BROKEN_ENCODING;
+ }
+}
+
+
+asn_dec_rval_t
+BOOLEAN_decode_xer(asn_codec_ctx_t *opt_codec_ctx,
+ asn_TYPE_descriptor_t *td, void **sptr, const char *opt_mname,
+ const void *buf_ptr, size_t size) {
+
+ return xer_decode_primitive(opt_codec_ctx, td,
+ sptr, sizeof(BOOLEAN_t), opt_mname, buf_ptr, size,
+ BOOLEAN__xer_body_decode);
+}
+
+asn_enc_rval_t
+BOOLEAN_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ const BOOLEAN_t *st = (const BOOLEAN_t *)sptr;
+ asn_enc_rval_t er;
+
+ (void)ilevel;
+ (void)flags;
+
+ if(!st) _ASN_ENCODE_FAILED;
+
+ if(*st) {
+ _ASN_CALLBACK("<true/>", 7);
+ er.encoded = 7;
+ } else {
+ _ASN_CALLBACK("<false/>", 8);
+ er.encoded = 8;
+ }
+
+ _ASN_ENCODED_OK(er);
+cb_failed:
+ _ASN_ENCODE_FAILED;
+}
+
+int
+BOOLEAN_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ const BOOLEAN_t *st = (const BOOLEAN_t *)sptr;
+ const char *buf;
+ size_t buflen;
+
+ (void)td; /* Unused argument */
+ (void)ilevel; /* Unused argument */
+
+ if(st) {
+ if(*st) {
+ buf = "TRUE";
+ buflen = 4;
+ } else {
+ buf = "FALSE";
+ buflen = 5;
+ }
+ } else {
+ buf = "<absent>";
+ buflen = 8;
+ }
+
+ return (cb(buf, buflen, app_key) < 0) ? -1 : 0;
+}
+
+void
+BOOLEAN_free(asn_TYPE_descriptor_t *td, void *ptr, int contents_only) {
+ if(td && ptr && !contents_only) {
+ FREEMEM(ptr);
+ }
+}
+
+asn_dec_rval_t
+BOOLEAN_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
+ asn_dec_rval_t rv;
+ BOOLEAN_t *st = (BOOLEAN_t *)*sptr;
+
+ (void)opt_codec_ctx;
+ (void)constraints;
+
+ if(!st) {
+ st = (BOOLEAN_t *)(*sptr = MALLOC(sizeof(*st)));
+ if(!st) _ASN_DECODE_FAILED;
+ }
+
+ /*
+ * Extract a single bit
+ */
+ switch(per_get_few_bits(pd, 1)) {
+ case 1: *st = 1; break;
+ case 0: *st = 0; break;
+ case -1: default: _ASN_DECODE_FAILED;
+ }
+
+ ASN_DEBUG("%s decoded as %s", td->name, *st ? "TRUE" : "FALSE");
+
+ rv.code = RC_OK;
+ rv.consumed = 1;
+ return rv;
+}
+
+
+asn_enc_rval_t
+BOOLEAN_encode_uper(asn_TYPE_descriptor_t *td,
+ asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
+ const BOOLEAN_t *st = (const BOOLEAN_t *)sptr;
+ asn_enc_rval_t er;
+
+ (void)constraints;
+
+ if(!st) _ASN_ENCODE_FAILED;
+
+ per_put_few_bits(po, *st ? 1 : 0, 1);
+
+ _ASN_ENCODED_OK(er);
+}
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "SMUX"
+ * found in "SMUX.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#include <asn_internal.h>
+
+#include "ClosePDU.h"
+
+int
+ClosePDU_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
+ asn_app_constraint_failed_f *ctfailcb, void *app_key) {
+ /* Replace with underlying type checker */
+ td->check_constraints = asn_DEF_INTEGER.check_constraints;
+ return td->check_constraints(td, sptr, ctfailcb, app_key);
+}
+
+/*
+ * This type is implemented using INTEGER,
+ * so here we adjust the DEF accordingly.
+ */
+static void
+ClosePDU_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
+ td->free_struct = asn_DEF_INTEGER.free_struct;
+ td->print_struct = asn_DEF_INTEGER.print_struct;
+ td->ber_decoder = asn_DEF_INTEGER.ber_decoder;
+ td->der_encoder = asn_DEF_INTEGER.der_encoder;
+ td->xer_decoder = asn_DEF_INTEGER.xer_decoder;
+ td->xer_encoder = asn_DEF_INTEGER.xer_encoder;
+ td->uper_decoder = asn_DEF_INTEGER.uper_decoder;
+ td->uper_encoder = asn_DEF_INTEGER.uper_encoder;
+ if(!td->per_constraints)
+ td->per_constraints = asn_DEF_INTEGER.per_constraints;
+ td->elements = asn_DEF_INTEGER.elements;
+ td->elements_count = asn_DEF_INTEGER.elements_count;
+ td->specifics = asn_DEF_INTEGER.specifics;
+}
+
+void
+ClosePDU_free(asn_TYPE_descriptor_t *td,
+ void *struct_ptr, int contents_only) {
+ ClosePDU_1_inherit_TYPE_descriptor(td);
+ td->free_struct(td, struct_ptr, contents_only);
+}
+
+int
+ClosePDU_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
+ int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
+ ClosePDU_1_inherit_TYPE_descriptor(td);
+ return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
+}
+
+asn_dec_rval_t
+ClosePDU_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ void **structure, const void *bufptr, size_t size, int tag_mode) {
+ ClosePDU_1_inherit_TYPE_descriptor(td);
+ return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode);
+}
+
+asn_enc_rval_t
+ClosePDU_encode_der(asn_TYPE_descriptor_t *td,
+ void *structure, int tag_mode, ber_tlv_tag_t tag,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ ClosePDU_1_inherit_TYPE_descriptor(td);
+ return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
+}
+
+asn_dec_rval_t
+ClosePDU_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ void **structure, const char *opt_mname, const void *bufptr, size_t size) {
+ ClosePDU_1_inherit_TYPE_descriptor(td);
+ return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size);
+}
+
+asn_enc_rval_t
+ClosePDU_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ ClosePDU_1_inherit_TYPE_descriptor(td);
+ return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
+}
+
+static ber_tlv_tag_t asn_DEF_ClosePDU_tags_1[] = {
+ (ASN_TAG_CLASS_APPLICATION | (1 << 2)),
+ (ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
+};
+asn_TYPE_descriptor_t asn_DEF_ClosePDU = {
+ "ClosePDU",
+ "ClosePDU",
+ ClosePDU_free,
+ ClosePDU_print,
+ ClosePDU_constraint,
+ ClosePDU_decode_ber,
+ ClosePDU_encode_der,
+ ClosePDU_decode_xer,
+ ClosePDU_encode_xer,
+ 0, 0, /* No PER support, use "-gen-PER" to enable */
+ 0, /* Use generic outmost tag fetcher */
+ asn_DEF_ClosePDU_tags_1,
+ sizeof(asn_DEF_ClosePDU_tags_1)
+ /sizeof(asn_DEF_ClosePDU_tags_1[0]) - 1, /* 1 */
+ asn_DEF_ClosePDU_tags_1, /* Same as above */
+ sizeof(asn_DEF_ClosePDU_tags_1)
+ /sizeof(asn_DEF_ClosePDU_tags_1[0]), /* 2 */
+ 0, /* No PER visible constraints */
+ 0, 0, /* Defined elsewhere */
+ 0 /* No specifics */
+};
+
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1155-SMI"
+ * found in "RFC1155-SMI.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#include <asn_internal.h>
+
+#include "Counter.h"
+
+int
+Counter_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
+ asn_app_constraint_failed_f *ctfailcb, void *app_key) {
+ const INTEGER_t *st = (const INTEGER_t *)sptr;
+ long value;
+
+ if(!sptr) {
+ _ASN_CTFAIL(app_key, td, sptr,
+ "%s: value not given (%s:%d)",
+ td->name, __FILE__, __LINE__);
+ return -1;
+ }
+
+ if(asn_INTEGER2long(st, &value)) {
+ _ASN_CTFAIL(app_key, td, sptr,
+ "%s: value too large (%s:%d)",
+ td->name, __FILE__, __LINE__);
+ return -1;
+ }
+
+ if((value >= 0 && value <= 4294967295)) {
+ /* Constraint check succeeded */
+ return 0;
+ } else {
+ _ASN_CTFAIL(app_key, td, sptr,
+ "%s: constraint failed (%s:%d)",
+ td->name, __FILE__, __LINE__);
+ return -1;
+ }
+}
+
+/*
+ * This type is implemented using INTEGER,
+ * so here we adjust the DEF accordingly.
+ */
+static void
+Counter_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
+ td->free_struct = asn_DEF_INTEGER.free_struct;
+ td->print_struct = asn_DEF_INTEGER.print_struct;
+ td->ber_decoder = asn_DEF_INTEGER.ber_decoder;
+ td->der_encoder = asn_DEF_INTEGER.der_encoder;
+ td->xer_decoder = asn_DEF_INTEGER.xer_decoder;
+ td->xer_encoder = asn_DEF_INTEGER.xer_encoder;
+ td->uper_decoder = asn_DEF_INTEGER.uper_decoder;
+ td->uper_encoder = asn_DEF_INTEGER.uper_encoder;
+ if(!td->per_constraints)
+ td->per_constraints = asn_DEF_INTEGER.per_constraints;
+ td->elements = asn_DEF_INTEGER.elements;
+ td->elements_count = asn_DEF_INTEGER.elements_count;
+ td->specifics = asn_DEF_INTEGER.specifics;
+}
+
+void
+Counter_free(asn_TYPE_descriptor_t *td,
+ void *struct_ptr, int contents_only) {
+ Counter_1_inherit_TYPE_descriptor(td);
+ td->free_struct(td, struct_ptr, contents_only);
+}
+
+int
+Counter_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
+ int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
+ Counter_1_inherit_TYPE_descriptor(td);
+ return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
+}
+
+asn_dec_rval_t
+Counter_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ void **structure, const void *bufptr, size_t size, int tag_mode) {
+ Counter_1_inherit_TYPE_descriptor(td);
+ return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode);
+}
+
+asn_enc_rval_t
+Counter_encode_der(asn_TYPE_descriptor_t *td,
+ void *structure, int tag_mode, ber_tlv_tag_t tag,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ Counter_1_inherit_TYPE_descriptor(td);
+ return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
+}
+
+asn_dec_rval_t
+Counter_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ void **structure, const char *opt_mname, const void *bufptr, size_t size) {
+ Counter_1_inherit_TYPE_descriptor(td);
+ return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size);
+}
+
+asn_enc_rval_t
+Counter_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ Counter_1_inherit_TYPE_descriptor(td);
+ return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
+}
+
+static ber_tlv_tag_t asn_DEF_Counter_tags_1[] = {
+ (ASN_TAG_CLASS_APPLICATION | (1 << 2)),
+ (ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
+};
+asn_TYPE_descriptor_t asn_DEF_Counter = {
+ "Counter",
+ "Counter",
+ Counter_free,
+ Counter_print,
+ Counter_constraint,
+ Counter_decode_ber,
+ Counter_encode_der,
+ Counter_decode_xer,
+ Counter_encode_xer,
+ 0, 0, /* No PER support, use "-gen-PER" to enable */
+ 0, /* Use generic outmost tag fetcher */
+ asn_DEF_Counter_tags_1,
+ sizeof(asn_DEF_Counter_tags_1)
+ /sizeof(asn_DEF_Counter_tags_1[0]) - 1, /* 1 */
+ asn_DEF_Counter_tags_1, /* Same as above */
+ sizeof(asn_DEF_Counter_tags_1)
+ /sizeof(asn_DEF_Counter_tags_1[0]), /* 2 */
+ 0, /* No PER visible constraints */
+ 0, 0, /* No members */
+ 0 /* No specifics */
+};
+
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1213-MIB"
+ * found in "RFC1213-MIB.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#include <asn_internal.h>
+
+#include "DisplayString.h"
+
+int
+DisplayString_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
+ asn_app_constraint_failed_f *ctfailcb, void *app_key) {
+ /* Replace with underlying type checker */
+ td->check_constraints = asn_DEF_OCTET_STRING.check_constraints;
+ return td->check_constraints(td, sptr, ctfailcb, app_key);
+}
+
+/*
+ * This type is implemented using OCTET_STRING,
+ * so here we adjust the DEF accordingly.
+ */
+static void
+DisplayString_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
+ td->free_struct = asn_DEF_OCTET_STRING.free_struct;
+ td->print_struct = asn_DEF_OCTET_STRING.print_struct;
+ td->ber_decoder = asn_DEF_OCTET_STRING.ber_decoder;
+ td->der_encoder = asn_DEF_OCTET_STRING.der_encoder;
+ td->xer_decoder = asn_DEF_OCTET_STRING.xer_decoder;
+ td->xer_encoder = asn_DEF_OCTET_STRING.xer_encoder;
+ td->uper_decoder = asn_DEF_OCTET_STRING.uper_decoder;
+ td->uper_encoder = asn_DEF_OCTET_STRING.uper_encoder;
+ if(!td->per_constraints)
+ td->per_constraints = asn_DEF_OCTET_STRING.per_constraints;
+ td->elements = asn_DEF_OCTET_STRING.elements;
+ td->elements_count = asn_DEF_OCTET_STRING.elements_count;
+ td->specifics = asn_DEF_OCTET_STRING.specifics;
+}
+
+void
+DisplayString_free(asn_TYPE_descriptor_t *td,
+ void *struct_ptr, int contents_only) {
+ DisplayString_1_inherit_TYPE_descriptor(td);
+ td->free_struct(td, struct_ptr, contents_only);
+}
+
+int
+DisplayString_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
+ int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
+ DisplayString_1_inherit_TYPE_descriptor(td);
+ return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
+}
+
+asn_dec_rval_t
+DisplayString_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ void **structure, const void *bufptr, size_t size, int tag_mode) {
+ DisplayString_1_inherit_TYPE_descriptor(td);
+ return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode);
+}
+
+asn_enc_rval_t
+DisplayString_encode_der(asn_TYPE_descriptor_t *td,
+ void *structure, int tag_mode, ber_tlv_tag_t tag,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ DisplayString_1_inherit_TYPE_descriptor(td);
+ return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
+}
+
+asn_dec_rval_t
+DisplayString_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ void **structure, const char *opt_mname, const void *bufptr, size_t size) {
+ DisplayString_1_inherit_TYPE_descriptor(td);
+ return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size);
+}
+
+asn_enc_rval_t
+DisplayString_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ DisplayString_1_inherit_TYPE_descriptor(td);
+ return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
+}
+
+static ber_tlv_tag_t asn_DEF_DisplayString_tags_1[] = {
+ (ASN_TAG_CLASS_UNIVERSAL | (4 << 2))
+};
+asn_TYPE_descriptor_t asn_DEF_DisplayString = {
+ "DisplayString",
+ "DisplayString",
+ DisplayString_free,
+ DisplayString_print,
+ DisplayString_constraint,
+ DisplayString_decode_ber,
+ DisplayString_encode_der,
+ DisplayString_decode_xer,
+ DisplayString_encode_xer,
+ 0, 0, /* No PER support, use "-gen-PER" to enable */
+ 0, /* Use generic outmost tag fetcher */
+ asn_DEF_DisplayString_tags_1,
+ sizeof(asn_DEF_DisplayString_tags_1)
+ /sizeof(asn_DEF_DisplayString_tags_1[0]), /* 1 */
+ asn_DEF_DisplayString_tags_1, /* Same as above */
+ sizeof(asn_DEF_DisplayString_tags_1)
+ /sizeof(asn_DEF_DisplayString_tags_1[0]), /* 1 */
+ 0, /* No PER visible constraints */
+ 0, 0, /* No members */
+ 0 /* No specifics */
+};
+
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1213-MIB"
+ * found in "RFC1213-MIB.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#include <asn_internal.h>
+
+#include "EgpNeighEntry.h"
+
+static asn_TYPE_member_t asn_MBR_EgpNeighEntry_1[] = {
+ { ATF_NOFLAGS, 0, offsetof(struct EgpNeighEntry, egpNeighState),
+ (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
+ 0,
+ &asn_DEF_INTEGER,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "egpNeighState"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct EgpNeighEntry, egpNeighAddr),
+ (ASN_TAG_CLASS_APPLICATION | (0 << 2)),
+ 0,
+ &asn_DEF_IpAddress,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "egpNeighAddr"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct EgpNeighEntry, egpNeighAs),
+ (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
+ 0,
+ &asn_DEF_INTEGER,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "egpNeighAs"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct EgpNeighEntry, egpNeighInMsgs),
+ (ASN_TAG_CLASS_APPLICATION | (1 << 2)),
+ 0,
+ &asn_DEF_Counter,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "egpNeighInMsgs"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct EgpNeighEntry, egpNeighInErrs),
+ (ASN_TAG_CLASS_APPLICATION | (1 << 2)),
+ 0,
+ &asn_DEF_Counter,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "egpNeighInErrs"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct EgpNeighEntry, egpNeighOutMsgs),
+ (ASN_TAG_CLASS_APPLICATION | (1 << 2)),
+ 0,
+ &asn_DEF_Counter,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "egpNeighOutMsgs"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct EgpNeighEntry, egpNeighOutErrs),
+ (ASN_TAG_CLASS_APPLICATION | (1 << 2)),
+ 0,
+ &asn_DEF_Counter,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "egpNeighOutErrs"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct EgpNeighEntry, egpNeighInErrMsgs),
+ (ASN_TAG_CLASS_APPLICATION | (1 << 2)),
+ 0,
+ &asn_DEF_Counter,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "egpNeighInErrMsgs"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct EgpNeighEntry, egpNeighOutErrMsgs),
+ (ASN_TAG_CLASS_APPLICATION | (1 << 2)),
+ 0,
+ &asn_DEF_Counter,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "egpNeighOutErrMsgs"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct EgpNeighEntry, egpNeighStateUps),
+ (ASN_TAG_CLASS_APPLICATION | (1 << 2)),
+ 0,
+ &asn_DEF_Counter,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "egpNeighStateUps"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct EgpNeighEntry, egpNeighStateDowns),
+ (ASN_TAG_CLASS_APPLICATION | (1 << 2)),
+ 0,
+ &asn_DEF_Counter,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "egpNeighStateDowns"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct EgpNeighEntry, egpNeighIntervalHello),
+ (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
+ 0,
+ &asn_DEF_INTEGER,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "egpNeighIntervalHello"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct EgpNeighEntry, egpNeighIntervalPoll),
+ (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
+ 0,
+ &asn_DEF_INTEGER,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "egpNeighIntervalPoll"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct EgpNeighEntry, egpNeighMode),
+ (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
+ 0,
+ &asn_DEF_INTEGER,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "egpNeighMode"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct EgpNeighEntry, egpNeighEventTrigger),
+ (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
+ 0,
+ &asn_DEF_INTEGER,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "egpNeighEventTrigger"
+ },
+};
+static ber_tlv_tag_t asn_DEF_EgpNeighEntry_tags_1[] = {
+ (ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
+};
+static asn_TYPE_tag2member_t asn_MAP_EgpNeighEntry_tag2el_1[] = {
+ { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 5 }, /* egpNeighState at 267 */
+ { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 2, -1, 4 }, /* egpNeighAs at 271 */
+ { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 11, -2, 3 }, /* egpNeighIntervalHello at 290 */
+ { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 12, -3, 2 }, /* egpNeighIntervalPoll at 292 */
+ { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 13, -4, 1 }, /* egpNeighMode at 294 */
+ { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 14, -5, 0 }, /* egpNeighEventTrigger at 297 */
+ { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 1, 0, 0 }, /* egpNeighAddr at 269 */
+ { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 3, 0, 7 }, /* egpNeighInMsgs at 273 */
+ { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 4, -1, 6 }, /* egpNeighInErrs at 275 */
+ { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 5, -2, 5 }, /* egpNeighOutMsgs at 277 */
+ { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 6, -3, 4 }, /* egpNeighOutErrs at 279 */
+ { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 7, -4, 3 }, /* egpNeighInErrMsgs at 282 */
+ { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 8, -5, 2 }, /* egpNeighOutErrMsgs at 284 */
+ { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 9, -6, 1 }, /* egpNeighStateUps at 286 */
+ { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 10, -7, 0 } /* egpNeighStateDowns at 288 */
+};
+static asn_SEQUENCE_specifics_t asn_SPC_EgpNeighEntry_specs_1 = {
+ sizeof(struct EgpNeighEntry),
+ offsetof(struct EgpNeighEntry, _asn_ctx),
+ asn_MAP_EgpNeighEntry_tag2el_1,
+ 15, /* Count of tags in the map */
+ 0, 0, 0, /* Optional elements (not needed) */
+ -1, /* Start extensions */
+ -1 /* Stop extensions */
+};
+asn_TYPE_descriptor_t asn_DEF_EgpNeighEntry = {
+ "EgpNeighEntry",
+ "EgpNeighEntry",
+ SEQUENCE_free,
+ SEQUENCE_print,
+ SEQUENCE_constraint,
+ SEQUENCE_decode_ber,
+ SEQUENCE_encode_der,
+ SEQUENCE_decode_xer,
+ SEQUENCE_encode_xer,
+ 0, 0, /* No PER support, use "-gen-PER" to enable */
+ 0, /* Use generic outmost tag fetcher */
+ asn_DEF_EgpNeighEntry_tags_1,
+ sizeof(asn_DEF_EgpNeighEntry_tags_1)
+ /sizeof(asn_DEF_EgpNeighEntry_tags_1[0]), /* 1 */
+ asn_DEF_EgpNeighEntry_tags_1, /* Same as above */
+ sizeof(asn_DEF_EgpNeighEntry_tags_1)
+ /sizeof(asn_DEF_EgpNeighEntry_tags_1[0]), /* 1 */
+ 0, /* No PER visible constraints */
+ asn_MBR_EgpNeighEntry_1,
+ 15, /* Elements count */
+ &asn_SPC_EgpNeighEntry_specs_1 /* Additional specs */
+};
+
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1155-SMI"
+ * found in "RFC1155-SMI.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#include <asn_internal.h>
+
+#include "Gauge.h"
+
+int
+Gauge_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
+ asn_app_constraint_failed_f *ctfailcb, void *app_key) {
+ const INTEGER_t *st = (const INTEGER_t *)sptr;
+ long value;
+
+ if(!sptr) {
+ _ASN_CTFAIL(app_key, td, sptr,
+ "%s: value not given (%s:%d)",
+ td->name, __FILE__, __LINE__);
+ return -1;
+ }
+
+ if(asn_INTEGER2long(st, &value)) {
+ _ASN_CTFAIL(app_key, td, sptr,
+ "%s: value too large (%s:%d)",
+ td->name, __FILE__, __LINE__);
+ return -1;
+ }
+
+ if((value >= 0 && value <= 4294967295)) {
+ /* Constraint check succeeded */
+ return 0;
+ } else {
+ _ASN_CTFAIL(app_key, td, sptr,
+ "%s: constraint failed (%s:%d)",
+ td->name, __FILE__, __LINE__);
+ return -1;
+ }
+}
+
+/*
+ * This type is implemented using INTEGER,
+ * so here we adjust the DEF accordingly.
+ */
+static void
+Gauge_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
+ td->free_struct = asn_DEF_INTEGER.free_struct;
+ td->print_struct = asn_DEF_INTEGER.print_struct;
+ td->ber_decoder = asn_DEF_INTEGER.ber_decoder;
+ td->der_encoder = asn_DEF_INTEGER.der_encoder;
+ td->xer_decoder = asn_DEF_INTEGER.xer_decoder;
+ td->xer_encoder = asn_DEF_INTEGER.xer_encoder;
+ td->uper_decoder = asn_DEF_INTEGER.uper_decoder;
+ td->uper_encoder = asn_DEF_INTEGER.uper_encoder;
+ if(!td->per_constraints)
+ td->per_constraints = asn_DEF_INTEGER.per_constraints;
+ td->elements = asn_DEF_INTEGER.elements;
+ td->elements_count = asn_DEF_INTEGER.elements_count;
+ td->specifics = asn_DEF_INTEGER.specifics;
+}
+
+void
+Gauge_free(asn_TYPE_descriptor_t *td,
+ void *struct_ptr, int contents_only) {
+ Gauge_1_inherit_TYPE_descriptor(td);
+ td->free_struct(td, struct_ptr, contents_only);
+}
+
+int
+Gauge_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
+ int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
+ Gauge_1_inherit_TYPE_descriptor(td);
+ return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
+}
+
+asn_dec_rval_t
+Gauge_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ void **structure, const void *bufptr, size_t size, int tag_mode) {
+ Gauge_1_inherit_TYPE_descriptor(td);
+ return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode);
+}
+
+asn_enc_rval_t
+Gauge_encode_der(asn_TYPE_descriptor_t *td,
+ void *structure, int tag_mode, ber_tlv_tag_t tag,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ Gauge_1_inherit_TYPE_descriptor(td);
+ return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
+}
+
+asn_dec_rval_t
+Gauge_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ void **structure, const char *opt_mname, const void *bufptr, size_t size) {
+ Gauge_1_inherit_TYPE_descriptor(td);
+ return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size);
+}
+
+asn_enc_rval_t
+Gauge_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ Gauge_1_inherit_TYPE_descriptor(td);
+ return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
+}
+
+static ber_tlv_tag_t asn_DEF_Gauge_tags_1[] = {
+ (ASN_TAG_CLASS_APPLICATION | (2 << 2)),
+ (ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
+};
+asn_TYPE_descriptor_t asn_DEF_Gauge = {
+ "Gauge",
+ "Gauge",
+ Gauge_free,
+ Gauge_print,
+ Gauge_constraint,
+ Gauge_decode_ber,
+ Gauge_encode_der,
+ Gauge_decode_xer,
+ Gauge_encode_xer,
+ 0, 0, /* No PER support, use "-gen-PER" to enable */
+ 0, /* Use generic outmost tag fetcher */
+ asn_DEF_Gauge_tags_1,
+ sizeof(asn_DEF_Gauge_tags_1)
+ /sizeof(asn_DEF_Gauge_tags_1[0]) - 1, /* 1 */
+ asn_DEF_Gauge_tags_1, /* Same as above */
+ sizeof(asn_DEF_Gauge_tags_1)
+ /sizeof(asn_DEF_Gauge_tags_1[0]), /* 2 */
+ 0, /* No PER visible constraints */
+ 0, 0, /* No members */
+ 0 /* No specifics */
+};
+
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1157-SNMP"
+ * found in "RFC1157-SNMP.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#include <asn_internal.h>
+
+#include "GetNextRequest-PDU.h"
+
+int
+GetNextRequest_PDU_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
+ asn_app_constraint_failed_f *ctfailcb, void *app_key) {
+ /* Replace with underlying type checker */
+ td->check_constraints = asn_DEF_PDU.check_constraints;
+ return td->check_constraints(td, sptr, ctfailcb, app_key);
+}
+
+/*
+ * This type is implemented using PDU,
+ * so here we adjust the DEF accordingly.
+ */
+static void
+GetNextRequest_PDU_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
+ td->free_struct = asn_DEF_PDU.free_struct;
+ td->print_struct = asn_DEF_PDU.print_struct;
+ td->ber_decoder = asn_DEF_PDU.ber_decoder;
+ td->der_encoder = asn_DEF_PDU.der_encoder;
+ td->xer_decoder = asn_DEF_PDU.xer_decoder;
+ td->xer_encoder = asn_DEF_PDU.xer_encoder;
+ td->uper_decoder = asn_DEF_PDU.uper_decoder;
+ td->uper_encoder = asn_DEF_PDU.uper_encoder;
+ if(!td->per_constraints)
+ td->per_constraints = asn_DEF_PDU.per_constraints;
+ td->elements = asn_DEF_PDU.elements;
+ td->elements_count = asn_DEF_PDU.elements_count;
+ td->specifics = asn_DEF_PDU.specifics;
+}
+
+void
+GetNextRequest_PDU_free(asn_TYPE_descriptor_t *td,
+ void *struct_ptr, int contents_only) {
+ GetNextRequest_PDU_1_inherit_TYPE_descriptor(td);
+ td->free_struct(td, struct_ptr, contents_only);
+}
+
+int
+GetNextRequest_PDU_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
+ int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
+ GetNextRequest_PDU_1_inherit_TYPE_descriptor(td);
+ return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
+}
+
+asn_dec_rval_t
+GetNextRequest_PDU_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ void **structure, const void *bufptr, size_t size, int tag_mode) {
+ GetNextRequest_PDU_1_inherit_TYPE_descriptor(td);
+ return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode);
+}
+
+asn_enc_rval_t
+GetNextRequest_PDU_encode_der(asn_TYPE_descriptor_t *td,
+ void *structure, int tag_mode, ber_tlv_tag_t tag,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ GetNextRequest_PDU_1_inherit_TYPE_descriptor(td);
+ return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
+}
+
+asn_dec_rval_t
+GetNextRequest_PDU_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ void **structure, const char *opt_mname, const void *bufptr, size_t size) {
+ GetNextRequest_PDU_1_inherit_TYPE_descriptor(td);
+ return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size);
+}
+
+asn_enc_rval_t
+GetNextRequest_PDU_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ GetNextRequest_PDU_1_inherit_TYPE_descriptor(td);
+ return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
+}
+
+static ber_tlv_tag_t asn_DEF_GetNextRequest_PDU_tags_1[] = {
+ (ASN_TAG_CLASS_CONTEXT | (1 << 2)),
+ (ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
+};
+asn_TYPE_descriptor_t asn_DEF_GetNextRequest_PDU = {
+ "GetNextRequest-PDU",
+ "GetNextRequest-PDU",
+ GetNextRequest_PDU_free,
+ GetNextRequest_PDU_print,
+ GetNextRequest_PDU_constraint,
+ GetNextRequest_PDU_decode_ber,
+ GetNextRequest_PDU_encode_der,
+ GetNextRequest_PDU_decode_xer,
+ GetNextRequest_PDU_encode_xer,
+ 0, 0, /* No PER support, use "-gen-PER" to enable */
+ 0, /* Use generic outmost tag fetcher */
+ asn_DEF_GetNextRequest_PDU_tags_1,
+ sizeof(asn_DEF_GetNextRequest_PDU_tags_1)
+ /sizeof(asn_DEF_GetNextRequest_PDU_tags_1[0]) - 1, /* 1 */
+ asn_DEF_GetNextRequest_PDU_tags_1, /* Same as above */
+ sizeof(asn_DEF_GetNextRequest_PDU_tags_1)
+ /sizeof(asn_DEF_GetNextRequest_PDU_tags_1[0]), /* 2 */
+ 0, /* No PER visible constraints */
+ 0, 0, /* Defined elsewhere */
+ 0 /* No specifics */
+};
+
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1157-SNMP"
+ * found in "RFC1157-SNMP.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#include <asn_internal.h>
+
+#include "GetRequest-PDU.h"
+
+int
+GetRequest_PDU_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
+ asn_app_constraint_failed_f *ctfailcb, void *app_key) {
+ /* Replace with underlying type checker */
+ td->check_constraints = asn_DEF_PDU.check_constraints;
+ return td->check_constraints(td, sptr, ctfailcb, app_key);
+}
+
+/*
+ * This type is implemented using PDU,
+ * so here we adjust the DEF accordingly.
+ */
+static void
+GetRequest_PDU_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
+ td->free_struct = asn_DEF_PDU.free_struct;
+ td->print_struct = asn_DEF_PDU.print_struct;
+ td->ber_decoder = asn_DEF_PDU.ber_decoder;
+ td->der_encoder = asn_DEF_PDU.der_encoder;
+ td->xer_decoder = asn_DEF_PDU.xer_decoder;
+ td->xer_encoder = asn_DEF_PDU.xer_encoder;
+ td->uper_decoder = asn_DEF_PDU.uper_decoder;
+ td->uper_encoder = asn_DEF_PDU.uper_encoder;
+ if(!td->per_constraints)
+ td->per_constraints = asn_DEF_PDU.per_constraints;
+ td->elements = asn_DEF_PDU.elements;
+ td->elements_count = asn_DEF_PDU.elements_count;
+ td->specifics = asn_DEF_PDU.specifics;
+}
+
+void
+GetRequest_PDU_free(asn_TYPE_descriptor_t *td,
+ void *struct_ptr, int contents_only) {
+ GetRequest_PDU_1_inherit_TYPE_descriptor(td);
+ td->free_struct(td, struct_ptr, contents_only);
+}
+
+int
+GetRequest_PDU_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
+ int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
+ GetRequest_PDU_1_inherit_TYPE_descriptor(td);
+ return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
+}
+
+asn_dec_rval_t
+GetRequest_PDU_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ void **structure, const void *bufptr, size_t size, int tag_mode) {
+ GetRequest_PDU_1_inherit_TYPE_descriptor(td);
+ return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode);
+}
+
+asn_enc_rval_t
+GetRequest_PDU_encode_der(asn_TYPE_descriptor_t *td,
+ void *structure, int tag_mode, ber_tlv_tag_t tag,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ GetRequest_PDU_1_inherit_TYPE_descriptor(td);
+ return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
+}
+
+asn_dec_rval_t
+GetRequest_PDU_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ void **structure, const char *opt_mname, const void *bufptr, size_t size) {
+ GetRequest_PDU_1_inherit_TYPE_descriptor(td);
+ return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size);
+}
+
+asn_enc_rval_t
+GetRequest_PDU_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ GetRequest_PDU_1_inherit_TYPE_descriptor(td);
+ return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
+}
+
+static ber_tlv_tag_t asn_DEF_GetRequest_PDU_tags_1[] = {
+ (ASN_TAG_CLASS_CONTEXT | (0 << 2)),
+ (ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
+};
+asn_TYPE_descriptor_t asn_DEF_GetRequest_PDU = {
+ "GetRequest-PDU",
+ "GetRequest-PDU",
+ GetRequest_PDU_free,
+ GetRequest_PDU_print,
+ GetRequest_PDU_constraint,
+ GetRequest_PDU_decode_ber,
+ GetRequest_PDU_encode_der,
+ GetRequest_PDU_decode_xer,
+ GetRequest_PDU_encode_xer,
+ 0, 0, /* No PER support, use "-gen-PER" to enable */
+ 0, /* Use generic outmost tag fetcher */
+ asn_DEF_GetRequest_PDU_tags_1,
+ sizeof(asn_DEF_GetRequest_PDU_tags_1)
+ /sizeof(asn_DEF_GetRequest_PDU_tags_1[0]) - 1, /* 1 */
+ asn_DEF_GetRequest_PDU_tags_1, /* Same as above */
+ sizeof(asn_DEF_GetRequest_PDU_tags_1)
+ /sizeof(asn_DEF_GetRequest_PDU_tags_1[0]), /* 2 */
+ 0, /* No PER visible constraints */
+ 0, 0, /* Defined elsewhere */
+ 0 /* No specifics */
+};
+
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1157-SNMP"
+ * found in "RFC1157-SNMP.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#include <asn_internal.h>
+
+#include "GetResponse-PDU.h"
+
+int
+GetResponse_PDU_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
+ asn_app_constraint_failed_f *ctfailcb, void *app_key) {
+ /* Replace with underlying type checker */
+ td->check_constraints = asn_DEF_PDU.check_constraints;
+ return td->check_constraints(td, sptr, ctfailcb, app_key);
+}
+
+/*
+ * This type is implemented using PDU,
+ * so here we adjust the DEF accordingly.
+ */
+static void
+GetResponse_PDU_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
+ td->free_struct = asn_DEF_PDU.free_struct;
+ td->print_struct = asn_DEF_PDU.print_struct;
+ td->ber_decoder = asn_DEF_PDU.ber_decoder;
+ td->der_encoder = asn_DEF_PDU.der_encoder;
+ td->xer_decoder = asn_DEF_PDU.xer_decoder;
+ td->xer_encoder = asn_DEF_PDU.xer_encoder;
+ td->uper_decoder = asn_DEF_PDU.uper_decoder;
+ td->uper_encoder = asn_DEF_PDU.uper_encoder;
+ if(!td->per_constraints)
+ td->per_constraints = asn_DEF_PDU.per_constraints;
+ td->elements = asn_DEF_PDU.elements;
+ td->elements_count = asn_DEF_PDU.elements_count;
+ td->specifics = asn_DEF_PDU.specifics;
+}
+
+void
+GetResponse_PDU_free(asn_TYPE_descriptor_t *td,
+ void *struct_ptr, int contents_only) {
+ GetResponse_PDU_1_inherit_TYPE_descriptor(td);
+ td->free_struct(td, struct_ptr, contents_only);
+}
+
+int
+GetResponse_PDU_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
+ int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
+ GetResponse_PDU_1_inherit_TYPE_descriptor(td);
+ return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
+}
+
+asn_dec_rval_t
+GetResponse_PDU_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ void **structure, const void *bufptr, size_t size, int tag_mode) {
+ GetResponse_PDU_1_inherit_TYPE_descriptor(td);
+ return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode);
+}
+
+asn_enc_rval_t
+GetResponse_PDU_encode_der(asn_TYPE_descriptor_t *td,
+ void *structure, int tag_mode, ber_tlv_tag_t tag,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ GetResponse_PDU_1_inherit_TYPE_descriptor(td);
+ return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
+}
+
+asn_dec_rval_t
+GetResponse_PDU_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ void **structure, const char *opt_mname, const void *bufptr, size_t size) {
+ GetResponse_PDU_1_inherit_TYPE_descriptor(td);
+ return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size);
+}
+
+asn_enc_rval_t
+GetResponse_PDU_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ GetResponse_PDU_1_inherit_TYPE_descriptor(td);
+ return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
+}
+
+static ber_tlv_tag_t asn_DEF_GetResponse_PDU_tags_1[] = {
+ (ASN_TAG_CLASS_CONTEXT | (2 << 2)),
+ (ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
+};
+asn_TYPE_descriptor_t asn_DEF_GetResponse_PDU = {
+ "GetResponse-PDU",
+ "GetResponse-PDU",
+ GetResponse_PDU_free,
+ GetResponse_PDU_print,
+ GetResponse_PDU_constraint,
+ GetResponse_PDU_decode_ber,
+ GetResponse_PDU_encode_der,
+ GetResponse_PDU_decode_xer,
+ GetResponse_PDU_encode_xer,
+ 0, 0, /* No PER support, use "-gen-PER" to enable */
+ 0, /* Use generic outmost tag fetcher */
+ asn_DEF_GetResponse_PDU_tags_1,
+ sizeof(asn_DEF_GetResponse_PDU_tags_1)
+ /sizeof(asn_DEF_GetResponse_PDU_tags_1[0]) - 1, /* 1 */
+ asn_DEF_GetResponse_PDU_tags_1, /* Same as above */
+ sizeof(asn_DEF_GetResponse_PDU_tags_1)
+ /sizeof(asn_DEF_GetResponse_PDU_tags_1[0]), /* 2 */
+ 0, /* No PER visible constraints */
+ 0, 0, /* Defined elsewhere */
+ 0 /* No specifics */
+};
+
--- /dev/null
+/*-
+ * Copyright (c) 2003, 2004, 2005, 2006 Lev Walkin <vlm@lionet.info>.
+ * All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#include <asn_internal.h>
+#include <INTEGER.h>
+#include <asn_codecs_prim.h> /* Encoder and decoder of a primitive type */
+#include <errno.h>
+
+/*
+ * INTEGER basic type description.
+ */
+static ber_tlv_tag_t asn_DEF_INTEGER_tags[] = {
+ (ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
+};
+asn_TYPE_descriptor_t asn_DEF_INTEGER = {
+ "INTEGER",
+ "INTEGER",
+ ASN__PRIMITIVE_TYPE_free,
+ INTEGER_print,
+ asn_generic_no_constraint,
+ ber_decode_primitive,
+ INTEGER_encode_der,
+ INTEGER_decode_xer,
+ INTEGER_encode_xer,
+ INTEGER_decode_uper, /* Unaligned PER decoder */
+ INTEGER_encode_uper, /* Unaligned PER encoder */
+ 0, /* Use generic outmost tag fetcher */
+ asn_DEF_INTEGER_tags,
+ sizeof(asn_DEF_INTEGER_tags) / sizeof(asn_DEF_INTEGER_tags[0]),
+ asn_DEF_INTEGER_tags, /* Same as above */
+ sizeof(asn_DEF_INTEGER_tags) / sizeof(asn_DEF_INTEGER_tags[0]),
+ 0, /* No PER visible constraints */
+ 0, 0, /* No members */
+ 0 /* No specifics */
+};
+
+/*
+ * Encode INTEGER type using DER.
+ */
+asn_enc_rval_t
+INTEGER_encode_der(asn_TYPE_descriptor_t *td, void *sptr,
+ int tag_mode, ber_tlv_tag_t tag,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ INTEGER_t *st = (INTEGER_t *)sptr;
+
+ ASN_DEBUG("%s %s as INTEGER (tm=%d)",
+ cb?"Encoding":"Estimating", td->name, tag_mode);
+
+ /*
+ * Canonicalize integer in the buffer.
+ * (Remove too long sign extension, remove some first 0x00 bytes)
+ */
+ if(st->buf) {
+ uint8_t *buf = st->buf;
+ uint8_t *end1 = buf + st->size - 1;
+ int shift;
+
+ /* Compute the number of superfluous leading bytes */
+ for(; buf < end1; buf++) {
+ /*
+ * If the contents octets of an integer value encoding
+ * consist of more than one octet, then the bits of the
+ * first octet and bit 8 of the second octet:
+ * a) shall not all be ones; and
+ * b) shall not all be zero.
+ */
+ switch(*buf) {
+ case 0x00: if((buf[1] & 0x80) == 0)
+ continue;
+ break;
+ case 0xff: if((buf[1] & 0x80))
+ continue;
+ break;
+ }
+ break;
+ }
+
+ /* Remove leading superfluous bytes from the integer */
+ shift = buf - st->buf;
+ if(shift) {
+ uint8_t *nb = st->buf;
+ uint8_t *end;
+
+ st->size -= shift; /* New size, minus bad bytes */
+ end = nb + st->size;
+
+ for(; nb < end; nb++, buf++)
+ *nb = *buf;
+ }
+
+ } /* if(1) */
+
+ return der_encode_primitive(td, sptr, tag_mode, tag, cb, app_key);
+}
+
+static const asn_INTEGER_enum_map_t *INTEGER_map_enum2value(asn_INTEGER_specifics_t *specs, const char *lstart, const char *lstop);
+
+/*
+ * INTEGER specific human-readable output.
+ */
+static ssize_t
+INTEGER__dump(asn_TYPE_descriptor_t *td, const INTEGER_t *st, asn_app_consume_bytes_f *cb, void *app_key, int plainOrXER) {
+ asn_INTEGER_specifics_t *specs=(asn_INTEGER_specifics_t *)td->specifics;
+ char scratch[32]; /* Enough for 64-bit integer */
+ uint8_t *buf = st->buf;
+ uint8_t *buf_end = st->buf + st->size;
+ signed long accum;
+ ssize_t wrote = 0;
+ char *p;
+ int ret;
+
+ /*
+ * Advance buf pointer until the start of the value's body.
+ * This will make us able to process large integers using simple case,
+ * when the actual value is small
+ * (0x0000000000abcdef would yield a fine 0x00abcdef)
+ */
+ /* Skip the insignificant leading bytes */
+ for(; buf < buf_end-1; buf++) {
+ switch(*buf) {
+ case 0x00: if((buf[1] & 0x80) == 0) continue; break;
+ case 0xff: if((buf[1] & 0x80) != 0) continue; break;
+ }
+ break;
+ }
+
+ /* Simple case: the integer size is small */
+ if((size_t)(buf_end - buf) <= sizeof(accum)) {
+ const asn_INTEGER_enum_map_t *el;
+ size_t scrsize;
+ char *scr;
+
+ if(buf == buf_end) {
+ accum = 0;
+ } else {
+ accum = (*buf & 0x80) ? -1 : 0;
+ for(; buf < buf_end; buf++)
+ accum = (accum << 8) | *buf;
+ }
+
+ el = INTEGER_map_value2enum(specs, accum);
+ if(el) {
+ scrsize = el->enum_len + 32;
+ scr = (char *)alloca(scrsize);
+ if(plainOrXER == 0)
+ ret = snprintf(scr, scrsize,
+ "%ld (%s)", accum, el->enum_name);
+ else
+ ret = snprintf(scr, scrsize,
+ "<%s/>", el->enum_name);
+ } else if(plainOrXER && specs && specs->strict_enumeration) {
+ ASN_DEBUG("ASN.1 forbids dealing with "
+ "unknown value of ENUMERATED type");
+ errno = EPERM;
+ return -1;
+ } else {
+ scrsize = sizeof(scratch);
+ scr = scratch;
+ ret = snprintf(scr, scrsize, "%ld", accum);
+ }
+ assert(ret > 0 && (size_t)ret < scrsize);
+ return (cb(scr, ret, app_key) < 0) ? -1 : ret;
+ } else if(plainOrXER && specs && specs->strict_enumeration) {
+ /*
+ * Here and earlier, we cannot encode the ENUMERATED values
+ * if there is no corresponding identifier.
+ */
+ ASN_DEBUG("ASN.1 forbids dealing with "
+ "unknown value of ENUMERATED type");
+ errno = EPERM;
+ return -1;
+ }
+
+ /* Output in the long xx:yy:zz... format */
+ /* TODO: replace with generic algorithm (Knuth TAOCP Vol 2, 4.3.1) */
+ for(p = scratch; buf < buf_end; buf++) {
+ static const char *h2c = "0123456789ABCDEF";
+ if((p - scratch) >= (ssize_t)(sizeof(scratch) - 4)) {
+ /* Flush buffer */
+ if(cb(scratch, p - scratch, app_key) < 0)
+ return -1;
+ wrote += p - scratch;
+ p = scratch;
+ }
+ *p++ = h2c[*buf >> 4];
+ *p++ = h2c[*buf & 0x0F];
+ *p++ = 0x3a; /* ":" */
+ }
+ if(p != scratch)
+ p--; /* Remove the last ":" */
+
+ wrote += p - scratch;
+ return (cb(scratch, p - scratch, app_key) < 0) ? -1 : wrote;
+}
+
+/*
+ * INTEGER specific human-readable output.
+ */
+int
+INTEGER_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ const INTEGER_t *st = (const INTEGER_t *)sptr;
+ ssize_t ret;
+
+ (void)td;
+ (void)ilevel;
+
+ if(!st || !st->buf)
+ ret = cb("<absent>", 8, app_key);
+ else
+ ret = INTEGER__dump(td, st, cb, app_key, 0);
+
+ return (ret < 0) ? -1 : 0;
+}
+
+struct e2v_key {
+ const char *start;
+ const char *stop;
+ asn_INTEGER_enum_map_t *vemap;
+ unsigned int *evmap;
+};
+static int
+INTEGER__compar_enum2value(const void *kp, const void *am) {
+ const struct e2v_key *key = (const struct e2v_key *)kp;
+ const asn_INTEGER_enum_map_t *el = (const asn_INTEGER_enum_map_t *)am;
+ const char *ptr, *end, *name;
+
+ /* Remap the element (sort by different criterion) */
+ el = key->vemap + key->evmap[el - key->vemap];
+
+ /* Compare strings */
+ for(ptr = key->start, end = key->stop, name = el->enum_name;
+ ptr < end; ptr++, name++) {
+ if(*ptr != *name)
+ return *(const unsigned char *)ptr
+ - *(const unsigned char *)name;
+ }
+ return name[0] ? -1 : 0;
+}
+
+static const asn_INTEGER_enum_map_t *
+INTEGER_map_enum2value(asn_INTEGER_specifics_t *specs, const char *lstart, const char *lstop) {
+ asn_INTEGER_enum_map_t *el_found;
+ int count = specs ? specs->map_count : 0;
+ struct e2v_key key;
+ const char *lp;
+
+ if(!count) return NULL;
+
+ /* Guaranteed: assert(lstart < lstop); */
+ /* Figure out the tag name */
+ for(lstart++, lp = lstart; lp < lstop; lp++) {
+ switch(*lp) {
+ case 9: case 10: case 11: case 12: case 13: case 32: /* WSP */
+ case 0x2f: /* '/' */ case 0x3e: /* '>' */
+ break;
+ default:
+ continue;
+ }
+ break;
+ }
+ if(lp == lstop) return NULL; /* No tag found */
+ lstop = lp;
+
+ key.start = lstart;
+ key.stop = lstop;
+ key.vemap = specs->value2enum;
+ key.evmap = specs->enum2value;
+ el_found = (asn_INTEGER_enum_map_t *)bsearch(&key,
+ specs->value2enum, count, sizeof(specs->value2enum[0]),
+ INTEGER__compar_enum2value);
+ if(el_found) {
+ /* Remap enum2value into value2enum */
+ el_found = key.vemap + key.evmap[el_found - key.vemap];
+ }
+ return el_found;
+}
+
+static int
+INTEGER__compar_value2enum(const void *kp, const void *am) {
+ long a = *(const long *)kp;
+ const asn_INTEGER_enum_map_t *el = (const asn_INTEGER_enum_map_t *)am;
+ long b = el->nat_value;
+ if(a < b) return -1;
+ else if(a == b) return 0;
+ else return 1;
+}
+
+const asn_INTEGER_enum_map_t *
+INTEGER_map_value2enum(asn_INTEGER_specifics_t *specs, long value) {
+ int count = specs ? specs->map_count : 0;
+ if(!count) return 0;
+ return (asn_INTEGER_enum_map_t *)bsearch(&value, specs->value2enum,
+ count, sizeof(specs->value2enum[0]),
+ INTEGER__compar_value2enum);
+}
+
+static int
+INTEGER_st_prealloc(INTEGER_t *st, int min_size) {
+ void *p = MALLOC(min_size + 1);
+ if(p) {
+ void *b = st->buf;
+ st->size = 0;
+ st->buf = p;
+ FREEMEM(b);
+ return 0;
+ } else {
+ return -1;
+ }
+}
+
+/*
+ * Decode the chunk of XML text encoding INTEGER.
+ */
+static enum xer_pbd_rval
+INTEGER__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chunk_buf, size_t chunk_size) {
+ INTEGER_t *st = (INTEGER_t *)sptr;
+ long sign = 1;
+ long value;
+ const char *lp;
+ const char *lstart = (const char *)chunk_buf;
+ const char *lstop = lstart + chunk_size;
+ enum {
+ ST_SKIPSPACE,
+ ST_SKIPSPHEX,
+ ST_WAITDIGITS,
+ ST_DIGITS,
+ ST_HEXDIGIT1,
+ ST_HEXDIGIT2,
+ ST_HEXCOLON,
+ ST_EXTRASTUFF
+ } state = ST_SKIPSPACE;
+
+ if(chunk_size)
+ ASN_DEBUG("INTEGER body %d 0x%2x..0x%2x",
+ chunk_size, *lstart, lstop[-1]);
+
+ /*
+ * We may have received a tag here. It will be processed inline.
+ * Use strtoul()-like code and serialize the result.
+ */
+ for(value = 0, lp = lstart; lp < lstop; lp++) {
+ int lv = *lp;
+ switch(lv) {
+ case 0x09: case 0x0a: case 0x0d: case 0x20:
+ switch(state) {
+ case ST_SKIPSPACE:
+ case ST_SKIPSPHEX:
+ continue;
+ case ST_HEXCOLON:
+ if(xer_is_whitespace(lp, lstop - lp)) {
+ lp = lstop - 1;
+ continue;
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ case 0x2d: /* '-' */
+ if(state == ST_SKIPSPACE) {
+ sign = -1;
+ state = ST_WAITDIGITS;
+ continue;
+ }
+ break;
+ case 0x2b: /* '+' */
+ if(state == ST_SKIPSPACE) {
+ state = ST_WAITDIGITS;
+ continue;
+ }
+ break;
+ case 0x30: case 0x31: case 0x32: case 0x33: case 0x34:
+ case 0x35: case 0x36: case 0x37: case 0x38: case 0x39:
+ switch(state) {
+ case ST_DIGITS: break;
+ case ST_SKIPSPHEX: /* Fall through */
+ case ST_HEXDIGIT1:
+ value = (lv - 0x30) << 4;
+ state = ST_HEXDIGIT2;
+ continue;
+ case ST_HEXDIGIT2:
+ value += (lv - 0x30);
+ state = ST_HEXCOLON;
+ st->buf[st->size++] = value;
+ continue;
+ case ST_HEXCOLON:
+ return XPBD_BROKEN_ENCODING;
+ default:
+ state = ST_DIGITS;
+ break;
+ }
+
+ {
+ long new_value = value * 10;
+
+ if(new_value / 10 != value)
+ /* Overflow */
+ return XPBD_DECODER_LIMIT;
+
+ value = new_value + (lv - 0x30);
+ /* Check for two's complement overflow */
+ if(value < 0) {
+ /* Check whether it is a LONG_MIN */
+ if(sign == -1
+ && (unsigned long)value
+ == ~((unsigned long)-1 >> 1)) {
+ sign = 1;
+ } else {
+ /* Overflow */
+ return XPBD_DECODER_LIMIT;
+ }
+ }
+ }
+ continue;
+ case 0x3c: /* '<' */
+ if(state == ST_SKIPSPACE) {
+ const asn_INTEGER_enum_map_t *el;
+ el = INTEGER_map_enum2value(
+ (asn_INTEGER_specifics_t *)
+ td->specifics, lstart, lstop);
+ if(el) {
+ ASN_DEBUG("Found \"%s\" => %ld",
+ el->enum_name, el->nat_value);
+ state = ST_DIGITS;
+ value = el->nat_value;
+ lp = lstop - 1;
+ continue;
+ }
+ ASN_DEBUG("Unknown identifier for INTEGER");
+ }
+ return XPBD_BROKEN_ENCODING;
+ case 0x3a: /* ':' */
+ if(state == ST_HEXCOLON) {
+ /* This colon is expected */
+ state = ST_HEXDIGIT1;
+ continue;
+ } else if(state == ST_DIGITS) {
+ /* The colon here means that we have
+ * decoded the first two hexadecimal
+ * places as a decimal value.
+ * Switch decoding mode. */
+ ASN_DEBUG("INTEGER re-evaluate as hex form");
+ if(INTEGER_st_prealloc(st, (chunk_size/3) + 1))
+ return XPBD_SYSTEM_FAILURE;
+ state = ST_SKIPSPHEX;
+ lp = lstart - 1;
+ continue;
+ } else {
+ ASN_DEBUG("state %d at %d", state, lp - lstart);
+ break;
+ }
+ /* [A-Fa-f] */
+ case 0x41:case 0x42:case 0x43:case 0x44:case 0x45:case 0x46:
+ case 0x61:case 0x62:case 0x63:case 0x64:case 0x65:case 0x66:
+ switch(state) {
+ case ST_SKIPSPHEX:
+ case ST_SKIPSPACE: /* Fall through */
+ case ST_HEXDIGIT1:
+ value = lv - ((lv < 0x61) ? 0x41 : 0x61);
+ value += 10;
+ value <<= 4;
+ state = ST_HEXDIGIT2;
+ continue;
+ case ST_HEXDIGIT2:
+ value += lv - ((lv < 0x61) ? 0x41 : 0x61);
+ value += 10;
+ st->buf[st->size++] = value;
+ state = ST_HEXCOLON;
+ continue;
+ case ST_DIGITS:
+ ASN_DEBUG("INTEGER re-evaluate as hex form");
+ if(INTEGER_st_prealloc(st, (chunk_size/3) + 1))
+ return XPBD_SYSTEM_FAILURE;
+ state = ST_SKIPSPHEX;
+ lp = lstart - 1;
+ continue;
+ default:
+ break;
+ }
+ break;
+ }
+
+ /* Found extra non-numeric stuff */
+ ASN_DEBUG("Found non-numeric 0x%2x at %d",
+ lv, lp - lstart);
+ state = ST_EXTRASTUFF;
+ break;
+ }
+
+ switch(state) {
+ case ST_DIGITS:
+ /* Everything is cool */
+ break;
+ case ST_HEXCOLON:
+ st->buf[st->size] = 0; /* Just in case termination */
+ return XPBD_BODY_CONSUMED;
+ case ST_HEXDIGIT1:
+ case ST_HEXDIGIT2:
+ case ST_SKIPSPHEX:
+ return XPBD_BROKEN_ENCODING;
+ default:
+ if(xer_is_whitespace(lp, lstop - lp)) {
+ if(state != ST_EXTRASTUFF)
+ return XPBD_NOT_BODY_IGNORE;
+ break;
+ } else {
+ ASN_DEBUG("INTEGER: No useful digits (state %d)",
+ state);
+ return XPBD_BROKEN_ENCODING; /* No digits */
+ }
+ break;
+ }
+
+ value *= sign; /* Change sign, if needed */
+
+ if(asn_long2INTEGER(st, value))
+ return XPBD_SYSTEM_FAILURE;
+
+ return XPBD_BODY_CONSUMED;
+}
+
+asn_dec_rval_t
+INTEGER_decode_xer(asn_codec_ctx_t *opt_codec_ctx,
+ asn_TYPE_descriptor_t *td, void **sptr, const char *opt_mname,
+ const void *buf_ptr, size_t size) {
+
+ return xer_decode_primitive(opt_codec_ctx, td,
+ sptr, sizeof(INTEGER_t), opt_mname,
+ buf_ptr, size, INTEGER__xer_body_decode);
+}
+
+asn_enc_rval_t
+INTEGER_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ const INTEGER_t *st = (const INTEGER_t *)sptr;
+ asn_enc_rval_t er;
+
+ (void)ilevel;
+ (void)flags;
+
+ if(!st || !st->buf)
+ _ASN_ENCODE_FAILED;
+
+ er.encoded = INTEGER__dump(td, st, cb, app_key, 1);
+ if(er.encoded < 0) _ASN_ENCODE_FAILED;
+
+ _ASN_ENCODED_OK(er);
+}
+
+asn_dec_rval_t
+INTEGER_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
+ asn_dec_rval_t rval = { RC_OK, 0 };
+ INTEGER_t *st = (INTEGER_t *)*sptr;
+ asn_per_constraint_t *ct;
+ int repeat;
+
+ (void)opt_codec_ctx;
+
+ if(!st) {
+ st = (INTEGER_t *)(*sptr = CALLOC(1, sizeof(*st)));
+ if(!st) _ASN_DECODE_FAILED;
+ }
+
+ if(!constraints) constraints = td->per_constraints;
+ ct = constraints ? &constraints->value : 0;
+
+ if(ct && ct->flags & APC_EXTENSIBLE) {
+ int inext = per_get_few_bits(pd, 1);
+ if(inext < 0) _ASN_DECODE_STARVED;
+ if(inext) ct = 0;
+ }
+
+ FREEMEM(st->buf);
+ if(ct) {
+ if(ct->flags & APC_SEMI_CONSTRAINED) {
+ st->buf = (uint8_t *)CALLOC(1, 2);
+ if(!st->buf) _ASN_DECODE_FAILED;
+ st->size = 1;
+ } else if(ct->flags & APC_CONSTRAINED && ct->range_bits >= 0) {
+ size_t size = (ct->range_bits + 7) >> 3;
+ st->buf = (uint8_t *)MALLOC(1 + size + 1);
+ if(!st->buf) _ASN_DECODE_FAILED;
+ st->size = size;
+ } else {
+ st->size = 0;
+ }
+ } else {
+ st->size = 0;
+ }
+
+ /* X.691, #12.2.2 */
+ if(ct && ct->flags != APC_UNCONSTRAINED) {
+ /* #10.5.6 */
+ ASN_DEBUG("Integer with range %d bits", ct->range_bits);
+ if(ct->range_bits >= 0) {
+ long value = per_get_few_bits(pd, ct->range_bits);
+ if(value < 0) _ASN_DECODE_STARVED;
+ ASN_DEBUG("Got value %ld + low %ld",
+ value, ct->lower_bound);
+ value += ct->lower_bound;
+ if(asn_long2INTEGER(st, value))
+ _ASN_DECODE_FAILED;
+ return rval;
+ }
+ } else {
+ ASN_DEBUG("Decoding unconstrained integer %s", td->name);
+ }
+
+ /* X.691, #12.2.3, #12.2.4 */
+ do {
+ ssize_t len;
+ void *p;
+ int ret;
+
+ /* Get the PER length */
+ len = uper_get_length(pd, -1, &repeat);
+ if(len < 0) _ASN_DECODE_STARVED;
+
+ p = REALLOC(st->buf, st->size + len + 1);
+ if(!p) _ASN_DECODE_FAILED;
+ st->buf = (uint8_t *)p;
+
+ ret = per_get_many_bits(pd, &st->buf[st->size], 0, 8 * len);
+ if(ret < 0) _ASN_DECODE_STARVED;
+ st->size += len;
+ } while(repeat);
+ st->buf[st->size] = 0; /* JIC */
+
+ /* #12.2.3 */
+ if(ct && ct->lower_bound) {
+ /*
+ * TODO: replace by in-place arithmetics.
+ */
+ long value;
+ if(asn_INTEGER2long(st, &value))
+ _ASN_DECODE_FAILED;
+ if(asn_long2INTEGER(st, value + ct->lower_bound))
+ _ASN_DECODE_FAILED;
+ }
+
+ return rval;
+}
+
+asn_enc_rval_t
+INTEGER_encode_uper(asn_TYPE_descriptor_t *td,
+ asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
+ asn_enc_rval_t er;
+ INTEGER_t *st = (INTEGER_t *)sptr;
+ const uint8_t *buf;
+ const uint8_t *end;
+ asn_per_constraint_t *ct;
+ long value = 0;
+
+ if(!st || st->size == 0) _ASN_ENCODE_FAILED;
+
+ if(!constraints) constraints = td->per_constraints;
+ ct = constraints ? &constraints->value : 0;
+
+ er.encoded = 0;
+
+ if(ct) {
+ int inext = 0;
+ if(asn_INTEGER2long(st, &value))
+ _ASN_ENCODE_FAILED;
+ /* Check proper range */
+ if(ct->flags & APC_SEMI_CONSTRAINED) {
+ if(value < ct->lower_bound)
+ inext = 1;
+ } else if(ct->range_bits >= 0) {
+ if(value < ct->lower_bound
+ || value > ct->upper_bound)
+ inext = 1;
+ }
+ ASN_DEBUG("Value %ld (%02x/%d) lb %ld ub %ld %s",
+ value, st->buf[0], st->size,
+ ct->lower_bound, ct->upper_bound,
+ inext ? "ext" : "fix");
+ if(ct->flags & APC_EXTENSIBLE) {
+ if(per_put_few_bits(po, inext, 1))
+ _ASN_ENCODE_FAILED;
+ if(inext) ct = 0;
+ } else if(inext) {
+ _ASN_ENCODE_FAILED;
+ }
+ }
+
+
+ /* X.691, #12.2.2 */
+ if(ct && ct->range_bits >= 0) {
+ /* #10.5.6 */
+ ASN_DEBUG("Encoding integer with range %d bits",
+ ct->range_bits);
+ if(per_put_few_bits(po, value - ct->lower_bound,
+ ct->range_bits))
+ _ASN_ENCODE_FAILED;
+ _ASN_ENCODED_OK(er);
+ }
+
+ if(ct && ct->lower_bound) {
+ ASN_DEBUG("Adjust lower bound to %ld", ct->lower_bound);
+ /* TODO: adjust lower bound */
+ _ASN_ENCODE_FAILED;
+ }
+
+ for(buf = st->buf, end = st->buf + st->size; buf < end;) {
+ ssize_t mayEncode = uper_put_length(po, end - buf);
+ if(mayEncode < 0)
+ _ASN_ENCODE_FAILED;
+ if(per_put_many_bits(po, buf, 8 * mayEncode))
+ _ASN_ENCODE_FAILED;
+ buf += mayEncode;
+ }
+
+ _ASN_ENCODED_OK(er);
+}
+
+int
+asn_INTEGER2long(const INTEGER_t *iptr, long *lptr) {
+ uint8_t *b, *end;
+ size_t size;
+ long l;
+
+ /* Sanity checking */
+ if(!iptr || !iptr->buf || !lptr) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ /* Cache the begin/end of the buffer */
+ b = iptr->buf; /* Start of the INTEGER buffer */
+ size = iptr->size;
+ end = b + size; /* Where to stop */
+
+ if(size > sizeof(long)) {
+ uint8_t *end1 = end - 1;
+ /*
+ * Slightly more advanced processing,
+ * able to >sizeof(long) bytes,
+ * when the actual value is small
+ * (0x0000000000abcdef would yield a fine 0x00abcdef)
+ */
+ /* Skip out the insignificant leading bytes */
+ for(; b < end1; b++) {
+ switch(*b) {
+ case 0x00: if((b[1] & 0x80) == 0) continue; break;
+ case 0xff: if((b[1] & 0x80) != 0) continue; break;
+ }
+ break;
+ }
+
+ size = end - b;
+ if(size > sizeof(long)) {
+ /* Still cannot fit the long */
+ errno = ERANGE;
+ return -1;
+ }
+ }
+
+ /* Shortcut processing of a corner case */
+ if(end == b) {
+ *lptr = 0;
+ return 0;
+ }
+
+ /* Perform the sign initialization */
+ /* Actually l = -(*b >> 7); gains nothing, yet unreadable! */
+ if((*b >> 7)) l = -1; else l = 0;
+
+ /* Conversion engine */
+ for(; b < end; b++)
+ l = (l << 8) | *b;
+
+ *lptr = l;
+ return 0;
+}
+
+int
+asn_long2INTEGER(INTEGER_t *st, long value) {
+ uint8_t *buf, *bp;
+ uint8_t *p;
+ uint8_t *pstart;
+ uint8_t *pend1;
+ int littleEndian = 1; /* Run-time detection */
+ int add;
+
+ if(!st) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ buf = (uint8_t *)MALLOC(sizeof(value));
+ if(!buf) return -1;
+
+ if(*(char *)&littleEndian) {
+ pstart = (uint8_t *)&value + sizeof(value) - 1;
+ pend1 = (uint8_t *)&value;
+ add = -1;
+ } else {
+ pstart = (uint8_t *)&value;
+ pend1 = pstart + sizeof(value) - 1;
+ add = 1;
+ }
+
+ /*
+ * If the contents octet consists of more than one octet,
+ * then bits of the first octet and bit 8 of the second octet:
+ * a) shall not all be ones; and
+ * b) shall not all be zero.
+ */
+ for(p = pstart; p != pend1; p += add) {
+ switch(*p) {
+ case 0x00: if((*(p+add) & 0x80) == 0)
+ continue;
+ break;
+ case 0xff: if((*(p+add) & 0x80))
+ continue;
+ break;
+ }
+ break;
+ }
+ /* Copy the integer body */
+ for(pstart = p, bp = buf, pend1 += add; p != pend1; p += add)
+ *bp++ = *p;
+
+ if(st->buf) FREEMEM(st->buf);
+ st->buf = buf;
+ st->size = bp - buf;
+
+ return 0;
+}
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1213-MIB"
+ * found in "RFC1213-MIB.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#include <asn_internal.h>
+
+#include "IfEntry.h"
+
+static asn_TYPE_member_t asn_MBR_IfEntry_1[] = {
+ { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifIndex),
+ (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
+ 0,
+ &asn_DEF_INTEGER,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "ifIndex"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifDescr),
+ (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)),
+ 0,
+ &asn_DEF_DisplayString,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "ifDescr"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifType),
+ (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
+ 0,
+ &asn_DEF_INTEGER,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "ifType"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifMtu),
+ (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
+ 0,
+ &asn_DEF_INTEGER,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "ifMtu"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifSpeed),
+ (ASN_TAG_CLASS_APPLICATION | (2 << 2)),
+ 0,
+ &asn_DEF_Gauge,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "ifSpeed"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifPhysAddress),
+ (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)),
+ 0,
+ &asn_DEF_PhysAddress,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "ifPhysAddress"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifAdminStatus),
+ (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
+ 0,
+ &asn_DEF_INTEGER,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "ifAdminStatus"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifOperStatus),
+ (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
+ 0,
+ &asn_DEF_INTEGER,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "ifOperStatus"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifLastChange),
+ (ASN_TAG_CLASS_APPLICATION | (3 << 2)),
+ 0,
+ &asn_DEF_TimeTicks,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "ifLastChange"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifInOctets),
+ (ASN_TAG_CLASS_APPLICATION | (1 << 2)),
+ 0,
+ &asn_DEF_Counter,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "ifInOctets"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifInUcastPkts),
+ (ASN_TAG_CLASS_APPLICATION | (1 << 2)),
+ 0,
+ &asn_DEF_Counter,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "ifInUcastPkts"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifInNUcastPkts),
+ (ASN_TAG_CLASS_APPLICATION | (1 << 2)),
+ 0,
+ &asn_DEF_Counter,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "ifInNUcastPkts"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifInDiscards),
+ (ASN_TAG_CLASS_APPLICATION | (1 << 2)),
+ 0,
+ &asn_DEF_Counter,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "ifInDiscards"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifInErrors),
+ (ASN_TAG_CLASS_APPLICATION | (1 << 2)),
+ 0,
+ &asn_DEF_Counter,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "ifInErrors"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifInUnknownProtos),
+ (ASN_TAG_CLASS_APPLICATION | (1 << 2)),
+ 0,
+ &asn_DEF_Counter,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "ifInUnknownProtos"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifOutOctets),
+ (ASN_TAG_CLASS_APPLICATION | (1 << 2)),
+ 0,
+ &asn_DEF_Counter,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "ifOutOctets"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifOutUcastPkts),
+ (ASN_TAG_CLASS_APPLICATION | (1 << 2)),
+ 0,
+ &asn_DEF_Counter,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "ifOutUcastPkts"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifOutNUcastPkts),
+ (ASN_TAG_CLASS_APPLICATION | (1 << 2)),
+ 0,
+ &asn_DEF_Counter,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "ifOutNUcastPkts"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifOutDiscards),
+ (ASN_TAG_CLASS_APPLICATION | (1 << 2)),
+ 0,
+ &asn_DEF_Counter,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "ifOutDiscards"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifOutErrors),
+ (ASN_TAG_CLASS_APPLICATION | (1 << 2)),
+ 0,
+ &asn_DEF_Counter,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "ifOutErrors"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifOutQLen),
+ (ASN_TAG_CLASS_APPLICATION | (2 << 2)),
+ 0,
+ &asn_DEF_Gauge,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "ifOutQLen"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct IfEntry, ifSpecific),
+ (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)),
+ 0,
+ &asn_DEF_OBJECT_IDENTIFIER,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "ifSpecific"
+ },
+};
+static ber_tlv_tag_t asn_DEF_IfEntry_tags_1[] = {
+ (ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
+};
+static asn_TYPE_tag2member_t asn_MAP_IfEntry_tag2el_1[] = {
+ { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 4 }, /* ifIndex at 78 */
+ { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 2, -1, 3 }, /* ifType at 83 */
+ { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 3, -2, 2 }, /* ifMtu at 85 */
+ { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 6, -3, 1 }, /* ifAdminStatus at 91 */
+ { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 7, -4, 0 }, /* ifOperStatus at 93 */
+ { (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 1, 0, 1 }, /* ifDescr at 81 */
+ { (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 5, -1, 0 }, /* ifPhysAddress at 89 */
+ { (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)), 21, 0, 0 }, /* ifSpecific at 121 */
+ { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 9, 0, 10 }, /* ifInOctets at 97 */
+ { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 10, -1, 9 }, /* ifInUcastPkts at 99 */
+ { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 11, -2, 8 }, /* ifInNUcastPkts at 101 */
+ { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 12, -3, 7 }, /* ifInDiscards at 103 */
+ { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 13, -4, 6 }, /* ifInErrors at 105 */
+ { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 14, -5, 5 }, /* ifInUnknownProtos at 107 */
+ { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 15, -6, 4 }, /* ifOutOctets at 109 */
+ { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 16, -7, 3 }, /* ifOutUcastPkts at 111 */
+ { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 17, -8, 2 }, /* ifOutNUcastPkts at 113 */
+ { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 18, -9, 1 }, /* ifOutDiscards at 115 */
+ { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 19, -10, 0 }, /* ifOutErrors at 117 */
+ { (ASN_TAG_CLASS_APPLICATION | (2 << 2)), 4, 0, 1 }, /* ifSpeed at 87 */
+ { (ASN_TAG_CLASS_APPLICATION | (2 << 2)), 20, -1, 0 }, /* ifOutQLen at 119 */
+ { (ASN_TAG_CLASS_APPLICATION | (3 << 2)), 8, 0, 0 } /* ifLastChange at 95 */
+};
+static asn_SEQUENCE_specifics_t asn_SPC_IfEntry_specs_1 = {
+ sizeof(struct IfEntry),
+ offsetof(struct IfEntry, _asn_ctx),
+ asn_MAP_IfEntry_tag2el_1,
+ 22, /* Count of tags in the map */
+ 0, 0, 0, /* Optional elements (not needed) */
+ -1, /* Start extensions */
+ -1 /* Stop extensions */
+};
+asn_TYPE_descriptor_t asn_DEF_IfEntry = {
+ "IfEntry",
+ "IfEntry",
+ SEQUENCE_free,
+ SEQUENCE_print,
+ SEQUENCE_constraint,
+ SEQUENCE_decode_ber,
+ SEQUENCE_encode_der,
+ SEQUENCE_decode_xer,
+ SEQUENCE_encode_xer,
+ 0, 0, /* No PER support, use "-gen-PER" to enable */
+ 0, /* Use generic outmost tag fetcher */
+ asn_DEF_IfEntry_tags_1,
+ sizeof(asn_DEF_IfEntry_tags_1)
+ /sizeof(asn_DEF_IfEntry_tags_1[0]), /* 1 */
+ asn_DEF_IfEntry_tags_1, /* Same as above */
+ sizeof(asn_DEF_IfEntry_tags_1)
+ /sizeof(asn_DEF_IfEntry_tags_1[0]), /* 1 */
+ 0, /* No PER visible constraints */
+ asn_MBR_IfEntry_1,
+ 22, /* Elements count */
+ &asn_SPC_IfEntry_specs_1 /* Additional specs */
+};
+
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1213-MIB"
+ * found in "RFC1213-MIB.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#include <asn_internal.h>
+
+#include "IpAddrEntry.h"
+
+static int
+memb_ipAdEntReasmMaxSize_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr,
+ asn_app_constraint_failed_f *ctfailcb, void *app_key) {
+ long value;
+
+ if(!sptr) {
+ _ASN_CTFAIL(app_key, td, sptr,
+ "%s: value not given (%s:%d)",
+ td->name, __FILE__, __LINE__);
+ return -1;
+ }
+
+ value = *(const long *)sptr;
+
+ if((value >= 0 && value <= 65535)) {
+ /* Constraint check succeeded */
+ return 0;
+ } else {
+ _ASN_CTFAIL(app_key, td, sptr,
+ "%s: constraint failed (%s:%d)",
+ td->name, __FILE__, __LINE__);
+ return -1;
+ }
+}
+
+static asn_TYPE_member_t asn_MBR_IpAddrEntry_1[] = {
+ { ATF_NOFLAGS, 0, offsetof(struct IpAddrEntry, ipAdEntAddr),
+ (ASN_TAG_CLASS_APPLICATION | (0 << 2)),
+ 0,
+ &asn_DEF_IpAddress,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "ipAdEntAddr"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct IpAddrEntry, ipAdEntIfIndex),
+ (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
+ 0,
+ &asn_DEF_INTEGER,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "ipAdEntIfIndex"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct IpAddrEntry, ipAdEntNetMask),
+ (ASN_TAG_CLASS_APPLICATION | (0 << 2)),
+ 0,
+ &asn_DEF_IpAddress,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "ipAdEntNetMask"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct IpAddrEntry, ipAdEntBcastAddr),
+ (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
+ 0,
+ &asn_DEF_INTEGER,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "ipAdEntBcastAddr"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct IpAddrEntry, ipAdEntReasmMaxSize),
+ (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
+ 0,
+ &asn_DEF_NativeInteger,
+ memb_ipAdEntReasmMaxSize_constraint_1,
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "ipAdEntReasmMaxSize"
+ },
+};
+static ber_tlv_tag_t asn_DEF_IpAddrEntry_tags_1[] = {
+ (ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
+};
+static asn_TYPE_tag2member_t asn_MAP_IpAddrEntry_tag2el_1[] = {
+ { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 1, 0, 2 }, /* ipAdEntIfIndex at 177 */
+ { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 3, -1, 1 }, /* ipAdEntBcastAddr at 181 */
+ { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 4, -2, 0 }, /* ipAdEntReasmMaxSize at 183 */
+ { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 0, 0, 1 }, /* ipAdEntAddr at 175 */
+ { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 2, -1, 0 } /* ipAdEntNetMask at 179 */
+};
+static asn_SEQUENCE_specifics_t asn_SPC_IpAddrEntry_specs_1 = {
+ sizeof(struct IpAddrEntry),
+ offsetof(struct IpAddrEntry, _asn_ctx),
+ asn_MAP_IpAddrEntry_tag2el_1,
+ 5, /* Count of tags in the map */
+ 0, 0, 0, /* Optional elements (not needed) */
+ -1, /* Start extensions */
+ -1 /* Stop extensions */
+};
+asn_TYPE_descriptor_t asn_DEF_IpAddrEntry = {
+ "IpAddrEntry",
+ "IpAddrEntry",
+ SEQUENCE_free,
+ SEQUENCE_print,
+ SEQUENCE_constraint,
+ SEQUENCE_decode_ber,
+ SEQUENCE_encode_der,
+ SEQUENCE_decode_xer,
+ SEQUENCE_encode_xer,
+ 0, 0, /* No PER support, use "-gen-PER" to enable */
+ 0, /* Use generic outmost tag fetcher */
+ asn_DEF_IpAddrEntry_tags_1,
+ sizeof(asn_DEF_IpAddrEntry_tags_1)
+ /sizeof(asn_DEF_IpAddrEntry_tags_1[0]), /* 1 */
+ asn_DEF_IpAddrEntry_tags_1, /* Same as above */
+ sizeof(asn_DEF_IpAddrEntry_tags_1)
+ /sizeof(asn_DEF_IpAddrEntry_tags_1[0]), /* 1 */
+ 0, /* No PER visible constraints */
+ asn_MBR_IpAddrEntry_1,
+ 5, /* Elements count */
+ &asn_SPC_IpAddrEntry_specs_1 /* Additional specs */
+};
+
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1155-SMI"
+ * found in "RFC1155-SMI.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#include <asn_internal.h>
+
+#include "IpAddress.h"
+
+int
+IpAddress_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
+ asn_app_constraint_failed_f *ctfailcb, void *app_key) {
+ const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr;
+ size_t size;
+
+ if(!sptr) {
+ _ASN_CTFAIL(app_key, td, sptr,
+ "%s: value not given (%s:%d)",
+ td->name, __FILE__, __LINE__);
+ return -1;
+ }
+
+ size = st->size;
+
+ if((size == 4)) {
+ /* Constraint check succeeded */
+ return 0;
+ } else {
+ _ASN_CTFAIL(app_key, td, sptr,
+ "%s: constraint failed (%s:%d)",
+ td->name, __FILE__, __LINE__);
+ return -1;
+ }
+}
+
+/*
+ * This type is implemented using OCTET_STRING,
+ * so here we adjust the DEF accordingly.
+ */
+static void
+IpAddress_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
+ td->free_struct = asn_DEF_OCTET_STRING.free_struct;
+ td->print_struct = asn_DEF_OCTET_STRING.print_struct;
+ td->ber_decoder = asn_DEF_OCTET_STRING.ber_decoder;
+ td->der_encoder = asn_DEF_OCTET_STRING.der_encoder;
+ td->xer_decoder = asn_DEF_OCTET_STRING.xer_decoder;
+ td->xer_encoder = asn_DEF_OCTET_STRING.xer_encoder;
+ td->uper_decoder = asn_DEF_OCTET_STRING.uper_decoder;
+ td->uper_encoder = asn_DEF_OCTET_STRING.uper_encoder;
+ if(!td->per_constraints)
+ td->per_constraints = asn_DEF_OCTET_STRING.per_constraints;
+ td->elements = asn_DEF_OCTET_STRING.elements;
+ td->elements_count = asn_DEF_OCTET_STRING.elements_count;
+ td->specifics = asn_DEF_OCTET_STRING.specifics;
+}
+
+void
+IpAddress_free(asn_TYPE_descriptor_t *td,
+ void *struct_ptr, int contents_only) {
+ IpAddress_1_inherit_TYPE_descriptor(td);
+ td->free_struct(td, struct_ptr, contents_only);
+}
+
+int
+IpAddress_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
+ int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
+ IpAddress_1_inherit_TYPE_descriptor(td);
+ return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
+}
+
+asn_dec_rval_t
+IpAddress_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ void **structure, const void *bufptr, size_t size, int tag_mode) {
+ IpAddress_1_inherit_TYPE_descriptor(td);
+ return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode);
+}
+
+asn_enc_rval_t
+IpAddress_encode_der(asn_TYPE_descriptor_t *td,
+ void *structure, int tag_mode, ber_tlv_tag_t tag,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ IpAddress_1_inherit_TYPE_descriptor(td);
+ return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
+}
+
+asn_dec_rval_t
+IpAddress_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ void **structure, const char *opt_mname, const void *bufptr, size_t size) {
+ IpAddress_1_inherit_TYPE_descriptor(td);
+ return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size);
+}
+
+asn_enc_rval_t
+IpAddress_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ IpAddress_1_inherit_TYPE_descriptor(td);
+ return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
+}
+
+static ber_tlv_tag_t asn_DEF_IpAddress_tags_1[] = {
+ (ASN_TAG_CLASS_APPLICATION | (0 << 2)),
+ (ASN_TAG_CLASS_UNIVERSAL | (4 << 2))
+};
+asn_TYPE_descriptor_t asn_DEF_IpAddress = {
+ "IpAddress",
+ "IpAddress",
+ IpAddress_free,
+ IpAddress_print,
+ IpAddress_constraint,
+ IpAddress_decode_ber,
+ IpAddress_encode_der,
+ IpAddress_decode_xer,
+ IpAddress_encode_xer,
+ 0, 0, /* No PER support, use "-gen-PER" to enable */
+ 0, /* Use generic outmost tag fetcher */
+ asn_DEF_IpAddress_tags_1,
+ sizeof(asn_DEF_IpAddress_tags_1)
+ /sizeof(asn_DEF_IpAddress_tags_1[0]) - 1, /* 1 */
+ asn_DEF_IpAddress_tags_1, /* Same as above */
+ sizeof(asn_DEF_IpAddress_tags_1)
+ /sizeof(asn_DEF_IpAddress_tags_1[0]), /* 2 */
+ 0, /* No PER visible constraints */
+ 0, 0, /* No members */
+ 0 /* No specifics */
+};
+
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1213-MIB"
+ * found in "RFC1213-MIB.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#include <asn_internal.h>
+
+#include "IpNetToMediaEntry.h"
+
+static asn_TYPE_member_t asn_MBR_IpNetToMediaEntry_1[] = {
+ { ATF_NOFLAGS, 0, offsetof(struct IpNetToMediaEntry, ipNetToMediaIfIndex),
+ (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
+ 0,
+ &asn_DEF_INTEGER,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "ipNetToMediaIfIndex"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct IpNetToMediaEntry, ipNetToMediaPhysAddress),
+ (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)),
+ 0,
+ &asn_DEF_PhysAddress,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "ipNetToMediaPhysAddress"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct IpNetToMediaEntry, ipNetToMediaNetAddress),
+ (ASN_TAG_CLASS_APPLICATION | (0 << 2)),
+ 0,
+ &asn_DEF_IpAddress,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "ipNetToMediaNetAddress"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct IpNetToMediaEntry, ipNetToMediaType),
+ (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
+ 0,
+ &asn_DEF_INTEGER,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "ipNetToMediaType"
+ },
+};
+static ber_tlv_tag_t asn_DEF_IpNetToMediaEntry_tags_1[] = {
+ (ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
+};
+static asn_TYPE_tag2member_t asn_MAP_IpNetToMediaEntry_tag2el_1[] = {
+ { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 1 }, /* ipNetToMediaIfIndex at 222 */
+ { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 3, -1, 0 }, /* ipNetToMediaType at 229 */
+ { (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 1, 0, 0 }, /* ipNetToMediaPhysAddress at 224 */
+ { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 2, 0, 0 } /* ipNetToMediaNetAddress at 226 */
+};
+static asn_SEQUENCE_specifics_t asn_SPC_IpNetToMediaEntry_specs_1 = {
+ sizeof(struct IpNetToMediaEntry),
+ offsetof(struct IpNetToMediaEntry, _asn_ctx),
+ asn_MAP_IpNetToMediaEntry_tag2el_1,
+ 4, /* Count of tags in the map */
+ 0, 0, 0, /* Optional elements (not needed) */
+ -1, /* Start extensions */
+ -1 /* Stop extensions */
+};
+asn_TYPE_descriptor_t asn_DEF_IpNetToMediaEntry = {
+ "IpNetToMediaEntry",
+ "IpNetToMediaEntry",
+ SEQUENCE_free,
+ SEQUENCE_print,
+ SEQUENCE_constraint,
+ SEQUENCE_decode_ber,
+ SEQUENCE_encode_der,
+ SEQUENCE_decode_xer,
+ SEQUENCE_encode_xer,
+ 0, 0, /* No PER support, use "-gen-PER" to enable */
+ 0, /* Use generic outmost tag fetcher */
+ asn_DEF_IpNetToMediaEntry_tags_1,
+ sizeof(asn_DEF_IpNetToMediaEntry_tags_1)
+ /sizeof(asn_DEF_IpNetToMediaEntry_tags_1[0]), /* 1 */
+ asn_DEF_IpNetToMediaEntry_tags_1, /* Same as above */
+ sizeof(asn_DEF_IpNetToMediaEntry_tags_1)
+ /sizeof(asn_DEF_IpNetToMediaEntry_tags_1[0]), /* 1 */
+ 0, /* No PER visible constraints */
+ asn_MBR_IpNetToMediaEntry_1,
+ 4, /* Elements count */
+ &asn_SPC_IpNetToMediaEntry_specs_1 /* Additional specs */
+};
+
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1213-MIB"
+ * found in "RFC1213-MIB.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#include <asn_internal.h>
+
+#include "IpRouteEntry.h"
+
+static asn_TYPE_member_t asn_MBR_IpRouteEntry_1[] = {
+ { ATF_NOFLAGS, 0, offsetof(struct IpRouteEntry, ipRouteDest),
+ (ASN_TAG_CLASS_APPLICATION | (0 << 2)),
+ 0,
+ &asn_DEF_IpAddress,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "ipRouteDest"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct IpRouteEntry, ipRouteIfIndex),
+ (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
+ 0,
+ &asn_DEF_INTEGER,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "ipRouteIfIndex"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct IpRouteEntry, ipRouteMetric1),
+ (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
+ 0,
+ &asn_DEF_INTEGER,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "ipRouteMetric1"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct IpRouteEntry, ipRouteMetric2),
+ (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
+ 0,
+ &asn_DEF_INTEGER,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "ipRouteMetric2"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct IpRouteEntry, ipRouteMetric3),
+ (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
+ 0,
+ &asn_DEF_INTEGER,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "ipRouteMetric3"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct IpRouteEntry, ipRouteMetric4),
+ (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
+ 0,
+ &asn_DEF_INTEGER,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "ipRouteMetric4"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct IpRouteEntry, ipRouteNextHop),
+ (ASN_TAG_CLASS_APPLICATION | (0 << 2)),
+ 0,
+ &asn_DEF_IpAddress,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "ipRouteNextHop"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct IpRouteEntry, ipRouteType),
+ (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
+ 0,
+ &asn_DEF_INTEGER,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "ipRouteType"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct IpRouteEntry, ipRouteProto),
+ (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
+ 0,
+ &asn_DEF_INTEGER,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "ipRouteProto"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct IpRouteEntry, ipRouteAge),
+ (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
+ 0,
+ &asn_DEF_INTEGER,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "ipRouteAge"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct IpRouteEntry, ipRouteMask),
+ (ASN_TAG_CLASS_APPLICATION | (0 << 2)),
+ 0,
+ &asn_DEF_IpAddress,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "ipRouteMask"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct IpRouteEntry, ipRouteMetric5),
+ (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
+ 0,
+ &asn_DEF_INTEGER,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "ipRouteMetric5"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct IpRouteEntry, ipRouteInfo),
+ (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)),
+ 0,
+ &asn_DEF_OBJECT_IDENTIFIER,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "ipRouteInfo"
+ },
+};
+static ber_tlv_tag_t asn_DEF_IpRouteEntry_tags_1[] = {
+ (ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
+};
+static asn_TYPE_tag2member_t asn_MAP_IpRouteEntry_tag2el_1[] = {
+ { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 1, 0, 8 }, /* ipRouteIfIndex at 192 */
+ { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 2, -1, 7 }, /* ipRouteMetric1 at 194 */
+ { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 3, -2, 6 }, /* ipRouteMetric2 at 196 */
+ { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 4, -3, 5 }, /* ipRouteMetric3 at 198 */
+ { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 5, -4, 4 }, /* ipRouteMetric4 at 200 */
+ { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 7, -5, 3 }, /* ipRouteType at 204 */
+ { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 8, -6, 2 }, /* ipRouteProto at 206 */
+ { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 9, -7, 1 }, /* ipRouteAge at 208 */
+ { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 11, -8, 0 }, /* ipRouteMetric5 at 212 */
+ { (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)), 12, 0, 0 }, /* ipRouteInfo at 215 */
+ { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 0, 0, 2 }, /* ipRouteDest at 190 */
+ { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 6, -1, 1 }, /* ipRouteNextHop at 202 */
+ { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 10, -2, 0 } /* ipRouteMask at 210 */
+};
+static asn_SEQUENCE_specifics_t asn_SPC_IpRouteEntry_specs_1 = {
+ sizeof(struct IpRouteEntry),
+ offsetof(struct IpRouteEntry, _asn_ctx),
+ asn_MAP_IpRouteEntry_tag2el_1,
+ 13, /* Count of tags in the map */
+ 0, 0, 0, /* Optional elements (not needed) */
+ -1, /* Start extensions */
+ -1 /* Stop extensions */
+};
+asn_TYPE_descriptor_t asn_DEF_IpRouteEntry = {
+ "IpRouteEntry",
+ "IpRouteEntry",
+ SEQUENCE_free,
+ SEQUENCE_print,
+ SEQUENCE_constraint,
+ SEQUENCE_decode_ber,
+ SEQUENCE_encode_der,
+ SEQUENCE_decode_xer,
+ SEQUENCE_encode_xer,
+ 0, 0, /* No PER support, use "-gen-PER" to enable */
+ 0, /* Use generic outmost tag fetcher */
+ asn_DEF_IpRouteEntry_tags_1,
+ sizeof(asn_DEF_IpRouteEntry_tags_1)
+ /sizeof(asn_DEF_IpRouteEntry_tags_1[0]), /* 1 */
+ asn_DEF_IpRouteEntry_tags_1, /* Same as above */
+ sizeof(asn_DEF_IpRouteEntry_tags_1)
+ /sizeof(asn_DEF_IpRouteEntry_tags_1[0]), /* 1 */
+ 0, /* No PER visible constraints */
+ asn_MBR_IpRouteEntry_1,
+ 13, /* Elements count */
+ &asn_SPC_IpRouteEntry_specs_1 /* Additional specs */
+};
+
--- /dev/null
+include ../../Makefile.conf
+
+LIB_NAME = stgsmux
+
+SRCS = $(wildcard *.c)
+
+INCS = $(notdir $(wildcard include/stg/*.h))
+
+LIB_INCS = -I ./include/stg
+
+#.PHONY: asn1
+
+#ASN1_SOURCES = RFC1213-MIB.asn1 \
+# RFC1155-SMI.asn1 \
+# RFC1157-SNMP.asn1 \
+# SMUX.asn1
+
+#asn1: $(ASN1_SOURCES)
+# asn1c -fskeletons-copy -fcompound-names $^
+# rm Makefile.am.sample
+
+include ../Makefile.in
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1157-SNMP"
+ * found in "RFC1157-SNMP.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#include <asn_internal.h>
+
+#include "Message.h"
+
+static asn_TYPE_member_t asn_MBR_Message_1[] = {
+ { ATF_NOFLAGS, 0, offsetof(struct Message, version),
+ (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
+ 0,
+ &asn_DEF_INTEGER,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "version"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct Message, community),
+ (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)),
+ 0,
+ &asn_DEF_OCTET_STRING,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "community"
+ },
+ { ATF_OPEN_TYPE | ATF_NOFLAGS, 0, offsetof(struct Message, data),
+ -1 /* Ambiguous tag (ANY?) */,
+ 0,
+ &asn_DEF_ANY,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "data"
+ },
+};
+static ber_tlv_tag_t asn_DEF_Message_tags_1[] = {
+ (ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
+};
+static asn_TYPE_tag2member_t asn_MAP_Message_tag2el_1[] = {
+ { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 0 }, /* version at 18 */
+ { (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 1, 0, 0 } /* community at 22 */
+};
+static asn_SEQUENCE_specifics_t asn_SPC_Message_specs_1 = {
+ sizeof(struct Message),
+ offsetof(struct Message, _asn_ctx),
+ asn_MAP_Message_tag2el_1,
+ 2, /* Count of tags in the map */
+ 0, 0, 0, /* Optional elements (not needed) */
+ -1, /* Start extensions */
+ -1 /* Stop extensions */
+};
+asn_TYPE_descriptor_t asn_DEF_Message = {
+ "Message",
+ "Message",
+ SEQUENCE_free,
+ SEQUENCE_print,
+ SEQUENCE_constraint,
+ SEQUENCE_decode_ber,
+ SEQUENCE_encode_der,
+ SEQUENCE_decode_xer,
+ SEQUENCE_encode_xer,
+ 0, 0, /* No PER support, use "-gen-PER" to enable */
+ 0, /* Use generic outmost tag fetcher */
+ asn_DEF_Message_tags_1,
+ sizeof(asn_DEF_Message_tags_1)
+ /sizeof(asn_DEF_Message_tags_1[0]), /* 1 */
+ asn_DEF_Message_tags_1, /* Same as above */
+ sizeof(asn_DEF_Message_tags_1)
+ /sizeof(asn_DEF_Message_tags_1[0]), /* 1 */
+ 0, /* No PER visible constraints */
+ asn_MBR_Message_1,
+ 3, /* Elements count */
+ &asn_SPC_Message_specs_1 /* Additional specs */
+};
+
--- /dev/null
+/*-
+ * Copyright (c) 2003, 2005 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#include <asn_internal.h>
+#include <asn_codecs_prim.h>
+#include <NULL.h>
+#include <BOOLEAN.h> /* Implemented in terms of BOOLEAN type */
+
+/*
+ * NULL basic type description.
+ */
+static ber_tlv_tag_t asn_DEF_NULL_tags[] = {
+ (ASN_TAG_CLASS_UNIVERSAL | (5 << 2))
+};
+asn_TYPE_descriptor_t asn_DEF_NULL = {
+ "NULL",
+ "NULL",
+ BOOLEAN_free,
+ NULL_print,
+ asn_generic_no_constraint,
+ BOOLEAN_decode_ber, /* Implemented in terms of BOOLEAN */
+ NULL_encode_der, /* Special handling of DER encoding */
+ NULL_decode_xer,
+ NULL_encode_xer,
+ NULL_decode_uper, /* Unaligned PER decoder */
+ NULL_encode_uper, /* Unaligned PER encoder */
+ 0, /* Use generic outmost tag fetcher */
+ asn_DEF_NULL_tags,
+ sizeof(asn_DEF_NULL_tags) / sizeof(asn_DEF_NULL_tags[0]),
+ asn_DEF_NULL_tags, /* Same as above */
+ sizeof(asn_DEF_NULL_tags) / sizeof(asn_DEF_NULL_tags[0]),
+ 0, /* No PER visible constraints */
+ 0, 0, /* No members */
+ 0 /* No specifics */
+};
+
+asn_enc_rval_t
+NULL_encode_der(asn_TYPE_descriptor_t *td, void *ptr,
+ int tag_mode, ber_tlv_tag_t tag,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ asn_enc_rval_t erval;
+
+ erval.encoded = der_write_tags(td, 0, tag_mode, 0, tag, cb, app_key);
+ if(erval.encoded == -1) {
+ erval.failed_type = td;
+ erval.structure_ptr = ptr;
+ }
+
+ _ASN_ENCODED_OK(erval);
+}
+
+asn_enc_rval_t
+NULL_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ asn_enc_rval_t er;
+
+ (void)td;
+ (void)sptr;
+ (void)ilevel;
+ (void)flags;
+ (void)cb;
+ (void)app_key;
+
+ /* XMLNullValue is empty */
+ er.encoded = 0;
+ _ASN_ENCODED_OK(er);
+}
+
+
+static enum xer_pbd_rval
+NULL__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chunk_buf, size_t chunk_size) {
+ (void)td;
+ (void)sptr;
+
+ if(xer_is_whitespace(chunk_buf, chunk_size))
+ return XPBD_BODY_CONSUMED;
+ else
+ return XPBD_BROKEN_ENCODING;
+}
+
+asn_dec_rval_t
+NULL_decode_xer(asn_codec_ctx_t *opt_codec_ctx,
+ asn_TYPE_descriptor_t *td, void **sptr, const char *opt_mname,
+ const void *buf_ptr, size_t size) {
+
+ return xer_decode_primitive(opt_codec_ctx, td,
+ sptr, sizeof(NULL_t), opt_mname, buf_ptr, size,
+ NULL__xer_body_decode);
+}
+
+int
+NULL_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+
+ (void)td; /* Unused argument */
+ (void)ilevel; /* Unused argument */
+
+ if(sptr) {
+ return (cb("<present>", 9, app_key) < 0) ? -1 : 0;
+ } else {
+ return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
+ }
+}
+
+asn_dec_rval_t
+NULL_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
+ asn_dec_rval_t rv;
+
+ (void)opt_codec_ctx;
+ (void)td;
+ (void)constraints;
+ (void)pd;
+
+ if(!*sptr) {
+ *sptr = MALLOC(sizeof(NULL_t));
+ if(*sptr) {
+ *(NULL_t *)*sptr = 0;
+ } else {
+ _ASN_DECODE_FAILED;
+ }
+ }
+
+ /*
+ * NULL type does not have content octets.
+ */
+
+ rv.code = RC_OK;
+ rv.consumed = 0;
+ return rv;
+}
+
+asn_enc_rval_t
+NULL_encode_uper(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints,
+ void *sptr, asn_per_outp_t *po) {
+ asn_enc_rval_t er;
+
+ (void)td;
+ (void)constraints;
+ (void)sptr;
+ (void)po;
+
+ er.encoded = 0;
+ _ASN_ENCODED_OK(er);
+}
--- /dev/null
+/*-
+ * Copyright (c) 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+/*
+ * Read the NativeInteger.h for the explanation wrt. differences between
+ * INTEGER and NativeInteger.
+ * Basically, both are decoders and encoders of ASN.1 INTEGER type, but this
+ * implementation deals with the standard (machine-specific) representation
+ * of them instead of using the platform-independent buffer.
+ */
+#include <asn_internal.h>
+#include <NativeEnumerated.h>
+
+/*
+ * NativeEnumerated basic type description.
+ */
+static ber_tlv_tag_t asn_DEF_NativeEnumerated_tags[] = {
+ (ASN_TAG_CLASS_UNIVERSAL | (10 << 2))
+};
+asn_TYPE_descriptor_t asn_DEF_NativeEnumerated = {
+ "ENUMERATED", /* The ASN.1 type is still ENUMERATED */
+ "ENUMERATED",
+ NativeInteger_free,
+ NativeInteger_print,
+ asn_generic_no_constraint,
+ NativeInteger_decode_ber,
+ NativeInteger_encode_der,
+ NativeInteger_decode_xer,
+ NativeEnumerated_encode_xer,
+ NativeEnumerated_decode_uper,
+ NativeEnumerated_encode_uper,
+ 0, /* Use generic outmost tag fetcher */
+ asn_DEF_NativeEnumerated_tags,
+ sizeof(asn_DEF_NativeEnumerated_tags) / sizeof(asn_DEF_NativeEnumerated_tags[0]),
+ asn_DEF_NativeEnumerated_tags, /* Same as above */
+ sizeof(asn_DEF_NativeEnumerated_tags) / sizeof(asn_DEF_NativeEnumerated_tags[0]),
+ 0, /* No PER visible constraints */
+ 0, 0, /* No members */
+ 0 /* No specifics */
+};
+
+asn_enc_rval_t
+NativeEnumerated_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ asn_INTEGER_specifics_t *specs=(asn_INTEGER_specifics_t *)td->specifics;
+ asn_enc_rval_t er;
+ const long *native = (const long *)sptr;
+ const asn_INTEGER_enum_map_t *el;
+
+ (void)ilevel;
+ (void)flags;
+
+ if(!native) _ASN_ENCODE_FAILED;
+
+ el = INTEGER_map_value2enum(specs, *native);
+ if(el) {
+ size_t srcsize = el->enum_len + 5;
+ char *src = (char *)alloca(srcsize);
+
+ er.encoded = snprintf(src, srcsize, "<%s/>", el->enum_name);
+ assert(er.encoded > 0 && (size_t)er.encoded < srcsize);
+ if(cb(src, er.encoded, app_key) < 0) _ASN_ENCODE_FAILED;
+ _ASN_ENCODED_OK(er);
+ } else {
+ ASN_DEBUG("ASN.1 forbids dealing with "
+ "unknown value of ENUMERATED type");
+ _ASN_ENCODE_FAILED;
+ }
+}
+
+asn_dec_rval_t
+NativeEnumerated_decode_uper(asn_codec_ctx_t *opt_codec_ctx,
+ asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints,
+ void **sptr, asn_per_data_t *pd) {
+ asn_INTEGER_specifics_t *specs = (asn_INTEGER_specifics_t *)td->specifics;
+ asn_dec_rval_t rval = { RC_OK, 0 };
+ long *native = (long *)*sptr;
+ asn_per_constraint_t *ct;
+ long value;
+
+ (void)opt_codec_ctx;
+
+ if(constraints) ct = &constraints->value;
+ else if(td->per_constraints) ct = &td->per_constraints->value;
+ else _ASN_DECODE_FAILED; /* Mandatory! */
+ if(!specs) _ASN_DECODE_FAILED;
+
+ if(!native) {
+ native = (long *)(*sptr = CALLOC(1, sizeof(*native)));
+ if(!native) _ASN_DECODE_FAILED;
+ }
+
+ ASN_DEBUG("Decoding %s as NativeEnumerated", td->name);
+
+ if(ct->flags & APC_EXTENSIBLE) {
+ int inext = per_get_few_bits(pd, 1);
+ if(inext < 0) _ASN_DECODE_STARVED;
+ if(inext) ct = 0;
+ }
+
+ if(ct && ct->range_bits >= 0) {
+ value = per_get_few_bits(pd, ct->range_bits);
+ if(value < 0) _ASN_DECODE_STARVED;
+ if(value >= (specs->extension
+ ? specs->extension - 1 : specs->map_count))
+ _ASN_DECODE_FAILED;
+ } else {
+ if(!specs->extension)
+ _ASN_DECODE_FAILED;
+ /*
+ * X.691, #10.6: normally small non-negative whole number;
+ */
+ value = uper_get_nsnnwn(pd);
+ if(value < 0) _ASN_DECODE_STARVED;
+ value += specs->extension - 1;
+ if(value >= specs->map_count)
+ _ASN_DECODE_FAILED;
+ }
+
+ *native = specs->value2enum[value].nat_value;
+ ASN_DEBUG("Decoded %s = %ld", td->name, *native);
+
+ return rval;
+}
+
+static int
+NativeEnumerated__compar_value2enum(const void *ap, const void *bp) {
+ const asn_INTEGER_enum_map_t *a = ap;
+ const asn_INTEGER_enum_map_t *b = bp;
+ if(a->nat_value == b->nat_value)
+ return 0;
+ if(a->nat_value < b->nat_value)
+ return -1;
+ return 1;
+}
+
+asn_enc_rval_t
+NativeEnumerated_encode_uper(asn_TYPE_descriptor_t *td,
+ asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
+ asn_INTEGER_specifics_t *specs = (asn_INTEGER_specifics_t *)td->specifics;
+ asn_enc_rval_t er;
+ long native, value;
+ asn_per_constraint_t *ct;
+ int inext = 0;
+ asn_INTEGER_enum_map_t key;
+ asn_INTEGER_enum_map_t *kf;
+
+ if(!sptr) _ASN_ENCODE_FAILED;
+ if(!specs) _ASN_ENCODE_FAILED;
+
+ if(constraints) ct = &constraints->value;
+ else if(td->per_constraints) ct = &td->per_constraints->value;
+ else _ASN_ENCODE_FAILED; /* Mandatory! */
+
+ ASN_DEBUG("Encoding %s as NativeEnumerated", td->name);
+
+ er.encoded = 0;
+
+ native = *(long *)sptr;
+ if(native < 0) _ASN_ENCODE_FAILED;
+
+ key.nat_value = native;
+ kf = bsearch(&key, specs->value2enum, specs->map_count,
+ sizeof(key), NativeEnumerated__compar_value2enum);
+ if(!kf) {
+ ASN_DEBUG("No element corresponds to %ld", native);
+ _ASN_ENCODE_FAILED;
+ }
+ value = kf - specs->value2enum;
+
+ if(ct->range_bits >= 0) {
+ int cmpWith = specs->extension
+ ? specs->extension - 1 : specs->map_count;
+ if(value >= cmpWith)
+ inext = 1;
+ }
+ if(ct->flags & APC_EXTENSIBLE) {
+ if(per_put_few_bits(po, inext, 0))
+ _ASN_ENCODE_FAILED;
+ ct = 0;
+ } else if(inext) {
+ _ASN_ENCODE_FAILED;
+ }
+
+ if(ct && ct->range_bits >= 0) {
+ if(per_put_few_bits(po, value, ct->range_bits))
+ _ASN_ENCODE_FAILED;
+ _ASN_ENCODED_OK(er);
+ }
+
+ if(!specs->extension)
+ _ASN_ENCODE_FAILED;
+
+ /*
+ * X.691, #10.6: normally small non-negative whole number;
+ */
+ if(uper_put_nsnnwn(po, value - (specs->extension - 1)))
+ _ASN_ENCODE_FAILED;
+
+ _ASN_ENCODED_OK(er);
+}
+
--- /dev/null
+/*-
+ * Copyright (c) 2004, 2005, 2006 Lev Walkin <vlm@lionet.info>.
+ * All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+/*
+ * Read the NativeInteger.h for the explanation wrt. differences between
+ * INTEGER and NativeInteger.
+ * Basically, both are decoders and encoders of ASN.1 INTEGER type, but this
+ * implementation deals with the standard (machine-specific) representation
+ * of them instead of using the platform-independent buffer.
+ */
+#include <asn_internal.h>
+#include <NativeInteger.h>
+
+/*
+ * NativeInteger basic type description.
+ */
+static ber_tlv_tag_t asn_DEF_NativeInteger_tags[] = {
+ (ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
+};
+asn_TYPE_descriptor_t asn_DEF_NativeInteger = {
+ "INTEGER", /* The ASN.1 type is still INTEGER */
+ "INTEGER",
+ NativeInteger_free,
+ NativeInteger_print,
+ asn_generic_no_constraint,
+ NativeInteger_decode_ber,
+ NativeInteger_encode_der,
+ NativeInteger_decode_xer,
+ NativeInteger_encode_xer,
+ NativeInteger_decode_uper, /* Unaligned PER decoder */
+ NativeInteger_encode_uper, /* Unaligned PER encoder */
+ 0, /* Use generic outmost tag fetcher */
+ asn_DEF_NativeInteger_tags,
+ sizeof(asn_DEF_NativeInteger_tags) / sizeof(asn_DEF_NativeInteger_tags[0]),
+ asn_DEF_NativeInteger_tags, /* Same as above */
+ sizeof(asn_DEF_NativeInteger_tags) / sizeof(asn_DEF_NativeInteger_tags[0]),
+ 0, /* No PER visible constraints */
+ 0, 0, /* No members */
+ 0 /* No specifics */
+};
+
+/*
+ * Decode INTEGER type.
+ */
+asn_dec_rval_t
+NativeInteger_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
+ asn_TYPE_descriptor_t *td,
+ void **nint_ptr, const void *buf_ptr, size_t size, int tag_mode) {
+ long *native = (long *)*nint_ptr;
+ asn_dec_rval_t rval;
+ ber_tlv_len_t length;
+
+ /*
+ * If the structure is not there, allocate it.
+ */
+ if(native == NULL) {
+ native = (long *)(*nint_ptr = CALLOC(1, sizeof(*native)));
+ if(native == NULL) {
+ rval.code = RC_FAIL;
+ rval.consumed = 0;
+ return rval;
+ }
+ }
+
+ ASN_DEBUG("Decoding %s as INTEGER (tm=%d)",
+ td->name, tag_mode);
+
+ /*
+ * Check tags.
+ */
+ rval = ber_check_tags(opt_codec_ctx, td, 0, buf_ptr, size,
+ tag_mode, 0, &length, 0);
+ if(rval.code != RC_OK)
+ return rval;
+
+ ASN_DEBUG("%s length is %d bytes", td->name, (int)length);
+
+ /*
+ * Make sure we have this length.
+ */
+ buf_ptr = ((const char *)buf_ptr) + rval.consumed;
+ size -= rval.consumed;
+ if(length > (ber_tlv_len_t)size) {
+ rval.code = RC_WMORE;
+ rval.consumed = 0;
+ return rval;
+ }
+
+ /*
+ * ASN.1 encoded INTEGER: buf_ptr, length
+ * Fill the native, at the same time checking for overflow.
+ * If overflow occured, return with RC_FAIL.
+ */
+ {
+ INTEGER_t tmp;
+ union {
+ const void *constbuf;
+ void *nonconstbuf;
+ } unconst_buf;
+ long l;
+
+ unconst_buf.constbuf = buf_ptr;
+ tmp.buf = (uint8_t *)unconst_buf.nonconstbuf;
+ tmp.size = length;
+
+ if(asn_INTEGER2long(&tmp, &l)) {
+ rval.code = RC_FAIL;
+ rval.consumed = 0;
+ return rval;
+ }
+
+ *native = l;
+ }
+
+ rval.code = RC_OK;
+ rval.consumed += length;
+
+ ASN_DEBUG("Took %ld/%ld bytes to encode %s (%ld)",
+ (long)rval.consumed, (long)length, td->name, (long)*native);
+
+ return rval;
+}
+
+/*
+ * Encode the NativeInteger using the standard INTEGER type DER encoder.
+ */
+asn_enc_rval_t
+NativeInteger_encode_der(asn_TYPE_descriptor_t *sd, void *ptr,
+ int tag_mode, ber_tlv_tag_t tag,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ unsigned long native = *(unsigned long *)ptr; /* Disable sign ext. */
+ asn_enc_rval_t erval;
+ INTEGER_t tmp;
+
+#ifdef WORDS_BIGENDIAN /* Opportunistic optimization */
+
+ tmp.buf = (uint8_t *)&native;
+ tmp.size = sizeof(native);
+
+#else /* Works even if WORDS_BIGENDIAN is not set where should've been */
+ uint8_t buf[sizeof(native)];
+ uint8_t *p;
+
+ /* Prepare a fake INTEGER */
+ for(p = buf + sizeof(buf) - 1; p >= buf; p--, native >>= 8)
+ *p = native;
+
+ tmp.buf = buf;
+ tmp.size = sizeof(buf);
+#endif /* WORDS_BIGENDIAN */
+
+ /* Encode fake INTEGER */
+ erval = INTEGER_encode_der(sd, &tmp, tag_mode, tag, cb, app_key);
+ if(erval.encoded == -1) {
+ assert(erval.structure_ptr == &tmp);
+ erval.structure_ptr = ptr;
+ }
+ return erval;
+}
+
+/*
+ * Decode the chunk of XML text encoding INTEGER.
+ */
+asn_dec_rval_t
+NativeInteger_decode_xer(asn_codec_ctx_t *opt_codec_ctx,
+ asn_TYPE_descriptor_t *td, void **sptr, const char *opt_mname,
+ const void *buf_ptr, size_t size) {
+ asn_dec_rval_t rval;
+ INTEGER_t st;
+ void *st_ptr = (void *)&st;
+ long *native = (long *)*sptr;
+
+ if(!native) {
+ native = (long *)(*sptr = CALLOC(1, sizeof(*native)));
+ if(!native) _ASN_DECODE_FAILED;
+ }
+
+ memset(&st, 0, sizeof(st));
+ rval = INTEGER_decode_xer(opt_codec_ctx, td, &st_ptr,
+ opt_mname, buf_ptr, size);
+ if(rval.code == RC_OK) {
+ long l;
+ if(asn_INTEGER2long(&st, &l)) {
+ rval.code = RC_FAIL;
+ rval.consumed = 0;
+ } else {
+ *native = l;
+ }
+ } else {
+ /*
+ * Cannot restart from the middle;
+ * there is no place to save state in the native type.
+ * Request a continuation from the very beginning.
+ */
+ rval.consumed = 0;
+ }
+ ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_INTEGER, &st);
+ return rval;
+}
+
+
+asn_enc_rval_t
+NativeInteger_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ char scratch[32]; /* Enough for 64-bit int */
+ asn_enc_rval_t er;
+ const long *native = (const long *)sptr;
+
+ (void)ilevel;
+ (void)flags;
+
+ if(!native) _ASN_ENCODE_FAILED;
+
+ er.encoded = snprintf(scratch, sizeof(scratch), "%ld", *native);
+ if(er.encoded <= 0 || (size_t)er.encoded >= sizeof(scratch)
+ || cb(scratch, er.encoded, app_key) < 0)
+ _ASN_ENCODE_FAILED;
+
+ _ASN_ENCODED_OK(er);
+}
+
+asn_dec_rval_t
+NativeInteger_decode_uper(asn_codec_ctx_t *opt_codec_ctx,
+ asn_TYPE_descriptor_t *td,
+ asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
+
+ asn_dec_rval_t rval;
+ long *native = (long *)*sptr;
+ INTEGER_t tmpint;
+ void *tmpintptr = &tmpint;
+
+ (void)opt_codec_ctx;
+ ASN_DEBUG("Decoding NativeInteger %s (UPER)", td->name);
+
+ if(!native) {
+ native = (long *)(*sptr = CALLOC(1, sizeof(*native)));
+ if(!native) _ASN_DECODE_FAILED;
+ }
+
+ memset(&tmpint, 0, sizeof tmpint);
+ rval = INTEGER_decode_uper(opt_codec_ctx, td, constraints,
+ &tmpintptr, pd);
+ if(rval.code == RC_OK) {
+ if(asn_INTEGER2long(&tmpint, native))
+ rval.code = RC_FAIL;
+ else
+ ASN_DEBUG("NativeInteger %s got value %ld",
+ td->name, *native);
+ }
+ ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_INTEGER, &tmpint);
+
+ return rval;
+}
+
+asn_enc_rval_t
+NativeInteger_encode_uper(asn_TYPE_descriptor_t *td,
+ asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
+ asn_enc_rval_t er;
+ long native;
+ INTEGER_t tmpint;
+
+ if(!sptr) _ASN_ENCODE_FAILED;
+
+ native = *(long *)sptr;
+
+ ASN_DEBUG("Encoding NativeInteger %s %ld (UPER)", td->name, native);
+
+ memset(&tmpint, 0, sizeof(tmpint));
+ if(asn_long2INTEGER(&tmpint, native))
+ _ASN_ENCODE_FAILED;
+ er = INTEGER_encode_uper(td, constraints, &tmpint, po);
+ ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_INTEGER, &tmpint);
+ return er;
+}
+
+/*
+ * INTEGER specific human-readable output.
+ */
+int
+NativeInteger_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ const long *native = (const long *)sptr;
+ char scratch[32]; /* Enough for 64-bit int */
+ int ret;
+
+ (void)td; /* Unused argument */
+ (void)ilevel; /* Unused argument */
+
+ if(native) {
+ ret = snprintf(scratch, sizeof(scratch), "%ld", *native);
+ assert(ret > 0 && (size_t)ret < sizeof(scratch));
+ return (cb(scratch, ret, app_key) < 0) ? -1 : 0;
+ } else {
+ return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
+ }
+}
+
+void
+NativeInteger_free(asn_TYPE_descriptor_t *td, void *ptr, int contents_only) {
+
+ if(!td || !ptr)
+ return;
+
+ ASN_DEBUG("Freeing %s as INTEGER (%d, %p, Native)",
+ td->name, contents_only, ptr);
+
+ if(!contents_only) {
+ FREEMEM(ptr);
+ }
+}
+
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1155-SMI"
+ * found in "RFC1155-SMI.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#include <asn_internal.h>
+
+#include "NetworkAddress.h"
+
+static asn_TYPE_member_t asn_MBR_NetworkAddress_1[] = {
+ { ATF_NOFLAGS, 0, offsetof(struct NetworkAddress, choice.internet),
+ (ASN_TAG_CLASS_APPLICATION | (0 << 2)),
+ 0,
+ &asn_DEF_IpAddress,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "internet"
+ },
+};
+static asn_TYPE_tag2member_t asn_MAP_NetworkAddress_tag2el_1[] = {
+ { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 0, 0, 0 } /* internet at 113 */
+};
+static asn_CHOICE_specifics_t asn_SPC_NetworkAddress_specs_1 = {
+ sizeof(struct NetworkAddress),
+ offsetof(struct NetworkAddress, _asn_ctx),
+ offsetof(struct NetworkAddress, present),
+ sizeof(((struct NetworkAddress *)0)->present),
+ asn_MAP_NetworkAddress_tag2el_1,
+ 1, /* Count of tags in the map */
+ 0,
+ -1 /* Extensions start */
+};
+asn_TYPE_descriptor_t asn_DEF_NetworkAddress = {
+ "NetworkAddress",
+ "NetworkAddress",
+ CHOICE_free,
+ CHOICE_print,
+ CHOICE_constraint,
+ CHOICE_decode_ber,
+ CHOICE_encode_der,
+ CHOICE_decode_xer,
+ CHOICE_encode_xer,
+ 0, 0, /* No PER support, use "-gen-PER" to enable */
+ CHOICE_outmost_tag,
+ 0, /* No effective tags (pointer) */
+ 0, /* No effective tags (count) */
+ 0, /* No tags (pointer) */
+ 0, /* No tags (count) */
+ 0, /* No PER visible constraints */
+ asn_MBR_NetworkAddress_1,
+ 1, /* Elements count */
+ &asn_SPC_NetworkAddress_specs_1 /* Additional specs */
+};
+
--- /dev/null
+/*-
+ * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#include <asn_internal.h>
+#include <OBJECT_IDENTIFIER.h>
+#include <limits.h> /* for CHAR_BIT */
+#include <errno.h>
+
+/*
+ * OBJECT IDENTIFIER basic type description.
+ */
+static ber_tlv_tag_t asn_DEF_OBJECT_IDENTIFIER_tags[] = {
+ (ASN_TAG_CLASS_UNIVERSAL | (6 << 2))
+};
+asn_TYPE_descriptor_t asn_DEF_OBJECT_IDENTIFIER = {
+ "OBJECT IDENTIFIER",
+ "OBJECT_IDENTIFIER",
+ ASN__PRIMITIVE_TYPE_free,
+ OBJECT_IDENTIFIER_print,
+ OBJECT_IDENTIFIER_constraint,
+ ber_decode_primitive,
+ der_encode_primitive,
+ OBJECT_IDENTIFIER_decode_xer,
+ OBJECT_IDENTIFIER_encode_xer,
+ 0, 0,
+ 0, /* Use generic outmost tag fetcher */
+ asn_DEF_OBJECT_IDENTIFIER_tags,
+ sizeof(asn_DEF_OBJECT_IDENTIFIER_tags)
+ / sizeof(asn_DEF_OBJECT_IDENTIFIER_tags[0]),
+ asn_DEF_OBJECT_IDENTIFIER_tags, /* Same as above */
+ sizeof(asn_DEF_OBJECT_IDENTIFIER_tags)
+ / sizeof(asn_DEF_OBJECT_IDENTIFIER_tags[0]),
+ 0, /* No PER visible constraints */
+ 0, 0, /* No members */
+ 0 /* No specifics */
+};
+
+
+int
+OBJECT_IDENTIFIER_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
+ asn_app_constraint_failed_f *ctfailcb, void *app_key) {
+ const OBJECT_IDENTIFIER_t *st = (const OBJECT_IDENTIFIER_t *)sptr;
+
+ if(st && st->buf) {
+ if(st->size < 1) {
+ _ASN_CTFAIL(app_key, td,
+ "%s: at least one numerical value "
+ "expected (%s:%d)",
+ td->name, __FILE__, __LINE__);
+ return -1;
+ }
+ } else {
+ _ASN_CTFAIL(app_key, td,
+ "%s: value not given (%s:%d)",
+ td->name, __FILE__, __LINE__);
+ return -1;
+ }
+
+ return 0;
+}
+
+
+int
+OBJECT_IDENTIFIER_get_single_arc(uint8_t *arcbuf, unsigned int arclen, signed int add, void *rvbufp, unsigned int rvsize) {
+ unsigned LE __attribute__ ((unused)) = 1; /* Little endian (x86) */
+ uint8_t *arcend = arcbuf + arclen; /* End of arc */
+ unsigned int cache = 0; /* No more than 14 significant bits */
+ unsigned char *rvbuf = (unsigned char *)rvbufp;
+ unsigned char *rvstart = rvbuf; /* Original start of the value buffer */
+ int inc; /* Return value growth direction */
+
+ rvsize *= CHAR_BIT; /* bytes to bits */
+ arclen *= 7; /* bytes to bits */
+
+ /*
+ * The arc has the number of bits
+ * cannot be represented using supplied return value type.
+ */
+ if(arclen > rvsize) {
+ if(arclen > (rvsize + CHAR_BIT)) {
+ errno = ERANGE; /* Overflow */
+ return -1;
+ } else {
+ /*
+ * Even if the number of bits in the arc representation
+ * is higher than the width of supplied * return value
+ * type, there is still possible to fit it when there
+ * are few unused high bits in the arc value
+ * representaion.
+ *
+ * Moreover, there is a possibility that the
+ * number could actually fit the arc space, given
+ * that add is negative, but we don't handle
+ * such "temporary lack of precision" situation here.
+ * May be considered as a bug.
+ */
+ uint8_t mask = (0xff << (7-(arclen - rvsize))) & 0x7f;
+ if((*arcbuf & mask)) {
+ errno = ERANGE; /* Overflow */
+ return -1;
+ }
+ /* Fool the routine computing unused bits */
+ arclen -= 7;
+ cache = *arcbuf & 0x7f;
+ arcbuf++;
+ }
+ }
+
+ /* Faster path for common size */
+ if(rvsize == (CHAR_BIT * sizeof(unsigned long))) {
+ unsigned long accum;
+ /* Gather all bits into the accumulator */
+ for(accum = cache; arcbuf < arcend; arcbuf++)
+ accum = (accum << 7) | (*arcbuf & ~0x80);
+ if(accum < (unsigned)-add) {
+ errno = ERANGE; /* Overflow */
+ return -1;
+ }
+ *(unsigned long *)rvbuf = accum + add; /* alignment OK! */
+ return 0;
+ }
+
+#ifndef WORDS_BIGENDIAN
+ if(*(unsigned char *)&LE) { /* Little endian (x86) */
+ /* "Convert" to big endian */
+ rvbuf += rvsize / CHAR_BIT - 1;
+ rvstart--;
+ inc = -1; /* Descending */
+ } else
+#endif /* !WORDS_BIGENDIAN */
+ inc = +1; /* Big endian is known [at compile time] */
+
+ {
+ int bits; /* typically no more than 3-4 bits */
+
+ /* Clear the high unused bits */
+ for(bits = rvsize - arclen;
+ bits > CHAR_BIT;
+ rvbuf += inc, bits -= CHAR_BIT)
+ *rvbuf = 0;
+
+ /* Fill the body of a value */
+ for(; arcbuf < arcend; arcbuf++) {
+ cache = (cache << 7) | (*arcbuf & 0x7f);
+ bits += 7;
+ if(bits >= CHAR_BIT) {
+ bits -= CHAR_BIT;
+ *rvbuf = (cache >> bits);
+ rvbuf += inc;
+ }
+ }
+ if(bits) {
+ *rvbuf = cache;
+ rvbuf += inc;
+ }
+ }
+
+ if(add) {
+ for(rvbuf -= inc; rvbuf != rvstart; rvbuf -= inc) {
+ int v = add + *rvbuf;
+ if(v & (-1 << CHAR_BIT)) {
+ *rvbuf = (unsigned char)(v + (1 << CHAR_BIT));
+ add = -1;
+ } else {
+ *rvbuf = v;
+ break;
+ }
+ }
+ if(rvbuf == rvstart) {
+ /* No space to carry over */
+ errno = ERANGE; /* Overflow */
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+ssize_t
+OBJECT_IDENTIFIER__dump_arc(uint8_t *arcbuf, int arclen, int add,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ char scratch[64]; /* Conservative estimate */
+ unsigned long accum; /* Bits accumulator */
+ char *p; /* Position in the scratch buffer */
+
+ if(OBJECT_IDENTIFIER_get_single_arc(arcbuf, arclen, add,
+ &accum, sizeof(accum)))
+ return -1;
+
+ if(accum) {
+ ssize_t len;
+
+ /* Fill the scratch buffer in reverse. */
+ p = scratch + sizeof(scratch);
+ for(; accum; accum /= 10)
+ *(--p) = (char)(accum % 10) + 0x30; /* Put a digit */
+
+ len = sizeof(scratch) - (p - scratch);
+ if(cb(p, len, app_key) < 0)
+ return -1;
+ return len;
+ } else {
+ *scratch = 0x30;
+ if(cb(scratch, 1, app_key) < 0)
+ return -1;
+ return 1;
+ }
+}
+
+int
+OBJECT_IDENTIFIER_print_arc(uint8_t *arcbuf, int arclen, int add,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+
+ if(OBJECT_IDENTIFIER__dump_arc(arcbuf, arclen, add, cb, app_key) < 0)
+ return -1;
+
+ return 0;
+}
+
+static ssize_t
+OBJECT_IDENTIFIER__dump_body(const OBJECT_IDENTIFIER_t *st, asn_app_consume_bytes_f *cb, void *app_key) {
+ ssize_t wrote_len = 0;
+ int startn;
+ int add = 0;
+ int i;
+
+ for(i = 0, startn = 0; i < st->size; i++) {
+ uint8_t b = st->buf[i];
+ if((b & 0x80)) /* Continuation expected */
+ continue;
+
+ if(startn == 0) {
+ /*
+ * First two arcs are encoded through the backdoor.
+ */
+ if(i) {
+ add = -80;
+ if(cb("2", 1, app_key) < 0) return -1;
+ } else if(b <= 39) {
+ add = 0;
+ if(cb("0", 1, app_key) < 0) return -1;
+ } else if(b < 79) {
+ add = -40;
+ if(cb("1", 1, app_key) < 0) return -1;
+ } else {
+ add = -80;
+ if(cb("2", 1, app_key) < 0) return -1;
+ }
+ wrote_len += 1;
+ }
+
+ if(cb(".", 1, app_key) < 0) /* Separate arcs */
+ return -1;
+
+ add = OBJECT_IDENTIFIER__dump_arc(&st->buf[startn],
+ i - startn + 1, add, cb, app_key);
+ if(add < 0) return -1;
+ wrote_len += 1 + add;
+ startn = i + 1;
+ add = 0;
+ }
+
+ return wrote_len;
+}
+
+static enum xer_pbd_rval
+OBJECT_IDENTIFIER__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chunk_buf, size_t chunk_size) {
+ OBJECT_IDENTIFIER_t *st = (OBJECT_IDENTIFIER_t *)sptr;
+ const char *chunk_end = (const char *)chunk_buf + chunk_size;
+ const char *endptr;
+ long s_arcs[10];
+ long *arcs = s_arcs;
+ int arcs_count;
+ int ret;
+
+ (void)td;
+
+ arcs_count = OBJECT_IDENTIFIER_parse_arcs(
+ (const char *)chunk_buf, chunk_size, arcs,
+ sizeof(s_arcs)/sizeof(s_arcs[0]), &endptr);
+ if(arcs_count <= 0) {
+ /* Expecting more than zero arcs */
+ return XPBD_BROKEN_ENCODING;
+ }
+ if(endptr < chunk_end) {
+ /* We have a tail of unrecognized data. Check its safety. */
+ if(!xer_is_whitespace(endptr, chunk_end - endptr))
+ return XPBD_BROKEN_ENCODING;
+ }
+
+ if((size_t)arcs_count > sizeof(s_arcs)/sizeof(s_arcs[0])) {
+ arcs = (long *)MALLOC(arcs_count * sizeof(long));
+ if(!arcs) return XPBD_SYSTEM_FAILURE;
+ ret = OBJECT_IDENTIFIER_parse_arcs(
+ (const char *)chunk_buf, chunk_size,
+ arcs, arcs_count, &endptr);
+ if(ret != arcs_count)
+ return XPBD_SYSTEM_FAILURE; /* assert?.. */
+ }
+
+ /*
+ * Convert arcs into BER representation.
+ */
+ ret = OBJECT_IDENTIFIER_set_arcs(st, arcs, sizeof(*arcs), arcs_count);
+ if(arcs != s_arcs) FREEMEM(arcs);
+
+ return ret ? XPBD_SYSTEM_FAILURE : XPBD_BODY_CONSUMED;
+}
+
+asn_dec_rval_t
+OBJECT_IDENTIFIER_decode_xer(asn_codec_ctx_t *opt_codec_ctx,
+ asn_TYPE_descriptor_t *td, void **sptr, const char *opt_mname,
+ const void *buf_ptr, size_t size) {
+
+ return xer_decode_primitive(opt_codec_ctx, td,
+ sptr, sizeof(OBJECT_IDENTIFIER_t), opt_mname,
+ buf_ptr, size, OBJECT_IDENTIFIER__xer_body_decode);
+}
+
+asn_enc_rval_t
+OBJECT_IDENTIFIER_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ const OBJECT_IDENTIFIER_t *st = (const OBJECT_IDENTIFIER_t *)sptr;
+ asn_enc_rval_t er;
+
+ (void)ilevel;
+ (void)flags;
+
+ if(!st || !st->buf)
+ _ASN_ENCODE_FAILED;
+
+ er.encoded = OBJECT_IDENTIFIER__dump_body(st, cb, app_key);
+ if(er.encoded < 0) _ASN_ENCODE_FAILED;
+
+ _ASN_ENCODED_OK(er);
+}
+
+int
+OBJECT_IDENTIFIER_print(asn_TYPE_descriptor_t *td, const void *sptr,
+ int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
+ const OBJECT_IDENTIFIER_t *st = (const OBJECT_IDENTIFIER_t *)sptr;
+
+ (void)td; /* Unused argument */
+ (void)ilevel; /* Unused argument */
+
+ if(!st || !st->buf)
+ return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
+
+ /* Dump preamble */
+ if(cb("{ ", 2, app_key) < 0)
+ return -1;
+
+ if(OBJECT_IDENTIFIER__dump_body(st, cb, app_key) < 0)
+ return -1;
+
+ return (cb(" }", 2, app_key) < 0) ? -1 : 0;
+}
+
+int
+OBJECT_IDENTIFIER_get_arcs(OBJECT_IDENTIFIER_t *oid, void *arcs,
+ unsigned int arc_type_size, unsigned int arc_slots) {
+ void *arcs_end = (char *)arcs + (arc_type_size * arc_slots);
+ int num_arcs = 0;
+ int startn = 0;
+ int add = 0;
+ int i;
+
+ if(!oid || !oid->buf || (arc_slots && arc_type_size <= 1)) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ for(i = 0; i < oid->size; i++) {
+ uint8_t b = oid->buf[i];
+ if((b & 0x80)) /* Continuation expected */
+ continue;
+
+ if(num_arcs == 0) {
+ /*
+ * First two arcs are encoded through the backdoor.
+ */
+ unsigned LE = 1; /* Little endian */
+ int first_arc;
+ num_arcs++;
+ if(!arc_slots) { num_arcs++; continue; }
+
+ if(i) first_arc = 2;
+ else if(b <= 39) first_arc = 0;
+ else if(b < 79) first_arc = 1;
+ else first_arc = 2;
+
+ add = -40 * first_arc;
+ memset(arcs, 0, arc_type_size);
+ *(unsigned char *)((char *)arcs
+ + ((*(char *)&LE)?0:(arc_type_size - 1)))
+ = first_arc;
+ arcs = ((char *)arcs) + arc_type_size;
+ }
+
+ /* Decode, if has space */
+ if(arcs < arcs_end) {
+ if(OBJECT_IDENTIFIER_get_single_arc(&oid->buf[startn],
+ i - startn + 1, add,
+ arcs, arc_type_size))
+ return -1;
+ startn = i + 1;
+ arcs = ((char *)arcs) + arc_type_size;
+ add = 0;
+ }
+ num_arcs++;
+ }
+
+ return num_arcs;
+}
+
+
+/*
+ * Save the single value as an object identifier arc.
+ */
+int
+OBJECT_IDENTIFIER_set_single_arc(uint8_t *arcbuf, const void *arcval, unsigned int arcval_size, int prepared_order) {
+ /*
+ * The following conditions must hold:
+ * assert(arcval);
+ * assert(arcval_size > 0);
+ * assert(arcval_size <= 16);
+ * assert(arcbuf);
+ */
+#ifdef WORDS_BIGENDIAN
+ const unsigned isLittleEndian = 0;
+#else
+ unsigned LE = 1;
+ unsigned isLittleEndian = *(char *)&LE;
+#endif
+ const uint8_t *tend, *tp;
+ unsigned int cache;
+ uint8_t *bp = arcbuf;
+ int bits;
+ uint8_t buffer[16];
+
+ if(isLittleEndian && !prepared_order) {
+ const uint8_t *a = (const unsigned char *)arcval + arcval_size - 1;
+ const uint8_t *aend = (const uint8_t *)arcval;
+ uint8_t *msb = buffer + arcval_size - 1;
+ uint8_t *tb;
+ for(tb = buffer; a >= aend; tb++, a--)
+ if((*tb = *a) && (tb < msb))
+ msb = tb;
+ tend = &buffer[arcval_size];
+ tp = msb; /* Most significant non-zero byte */
+ } else {
+ /* Look for most significant non-zero byte */
+ tend = (const unsigned char *)arcval + arcval_size;
+ for(tp = (const uint8_t *)arcval; tp < tend - 1; tp++)
+ if(*tp) break;
+ }
+
+ /*
+ * Split the value in 7-bits chunks.
+ */
+ bits = ((tend - tp) * CHAR_BIT) % 7;
+ if(bits) {
+ cache = *tp >> (CHAR_BIT - bits);
+ if(cache) {
+ *bp++ = cache | 0x80;
+ cache = *tp++;
+ bits = CHAR_BIT - bits;
+ } else {
+ bits = -bits;
+ }
+ } else {
+ cache = 0;
+ }
+ for(; tp < tend; tp++) {
+ cache = (cache << CHAR_BIT) + *tp;
+ bits += CHAR_BIT;
+ while(bits >= 7) {
+ bits -= 7;
+ *bp++ = 0x80 | (cache >> bits);
+ }
+ }
+ if(bits) *bp++ = cache;
+ bp[-1] &= 0x7f; /* Clear the last bit */
+
+ return bp - arcbuf;
+}
+
+int
+OBJECT_IDENTIFIER_set_arcs(OBJECT_IDENTIFIER_t *oid, const void *arcs, unsigned int arc_type_size, unsigned int arc_slots) {
+ uint8_t *buf;
+ uint8_t *bp;
+ unsigned LE = 1; /* Little endian (x86) */
+ unsigned isLittleEndian = *((char *)&LE);
+ unsigned int arc0;
+ unsigned int arc1;
+ unsigned size;
+ unsigned i;
+
+ if(!oid || !arcs || arc_type_size < 1
+ || arc_type_size > 16
+ || arc_slots < 2) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ switch(arc_type_size) {
+ case sizeof(char):
+ arc0 = ((const unsigned char *)arcs)[0];
+ arc1 = ((const unsigned char *)arcs)[1];
+ break;
+ case sizeof(short):
+ arc0 = ((const unsigned short *)arcs)[0];
+ arc1 = ((const unsigned short *)arcs)[1];
+ break;
+ case sizeof(int):
+ arc0 = ((const unsigned int *)arcs)[0];
+ arc1 = ((const unsigned int *)arcs)[1];
+ break;
+ default:
+ arc1 = arc0 = 0;
+ if(isLittleEndian) { /* Little endian (x86) */
+ const unsigned char *ps, *pe;
+ /* If more significant bytes are present,
+ * make them > 255 quick */
+ for(ps = (const unsigned char *)arcs + 1, pe = ps+arc_type_size;
+ ps < pe; ps++)
+ arc0 |= *ps, arc1 |= *(ps + arc_type_size);
+ arc0 <<= CHAR_BIT, arc1 <<= CHAR_BIT;
+ arc0 = *((const unsigned char *)arcs + 0);
+ arc1 = *((const unsigned char *)arcs + arc_type_size);
+ } else {
+ const unsigned char *ps, *pe;
+ /* If more significant bytes are present,
+ * make them > 255 quick */
+ for(ps = (const unsigned char *)arcs, pe = ps+arc_type_size - 1; ps < pe; ps++)
+ arc0 |= *ps, arc1 |= *(ps + arc_type_size);
+ arc0 = *((const unsigned char *)arcs + arc_type_size - 1);
+ arc1 = *((const unsigned char *)arcs +(arc_type_size<< 1)-1);
+ }
+ }
+
+ /*
+ * The previous chapter left us with the first and the second arcs.
+ * The values are not precise (that is, they are valid only if
+ * they're less than 255), but OK for the purposes of making
+ * the sanity test below.
+ */
+ if(arc0 <= 1) {
+ if(arc1 >= 39) {
+ /* 8.19.4: At most 39 subsequent values (including 0) */
+ errno = ERANGE;
+ return -1;
+ }
+ } else if(arc0 > 2) {
+ /* 8.19.4: Only three values are allocated from the root node */
+ errno = ERANGE;
+ return -1;
+ }
+ /*
+ * After above tests it is known that the value of arc0 is completely
+ * trustworthy (0..2). However, the arc1's value is still meaningless.
+ */
+
+ /*
+ * Roughly estimate the maximum size necessary to encode these arcs.
+ * This estimation implicitly takes in account the following facts,
+ * that cancel each other:
+ * * the first two arcs are encoded in a single value.
+ * * the first value may require more space (+1 byte)
+ * * the value of the first arc which is in range (0..2)
+ */
+ size = ((arc_type_size * CHAR_BIT + 6) / 7) * arc_slots;
+ bp = buf = (uint8_t *)MALLOC(size + 1);
+ if(!buf) {
+ /* ENOMEM */
+ return -1;
+ }
+
+ /*
+ * Encode the first two arcs.
+ * These require special treatment.
+ */
+ {
+ uint8_t *tp;
+ uint8_t first_value[1 + 16]; /* of two arcs */
+ uint8_t *fv = first_value;
+
+ /*
+ * Simulate first_value = arc0 * 40 + arc1;
+ */
+ /* Copy the second (1'st) arcs[1] into the first_value */
+ *fv++ = 0;
+ arcs = ((const char *)arcs) + arc_type_size;
+ if(isLittleEndian) {
+ const uint8_t *aend = (const unsigned char *)arcs - 1;
+ const uint8_t *a1 = (const unsigned char *)arcs + arc_type_size - 1;
+ for(; a1 > aend; fv++, a1--) *fv = *a1;
+ } else {
+ const uint8_t *a1 = (const uint8_t *)arcs;
+ const uint8_t *aend = a1 + arc_type_size;
+ for(; a1 < aend; fv++, a1++) *fv = *a1;
+ }
+ /* Increase the first_value by arc0 */
+ arc0 *= 40; /* (0..80) */
+ for(tp = first_value + arc_type_size; tp >= first_value; tp--) {
+ unsigned int v = *tp;
+ v += arc0;
+ *tp = v;
+ if(v >= (1 << CHAR_BIT)) arc0 = v >> CHAR_BIT;
+ else break;
+ }
+
+ assert(tp >= first_value);
+
+ bp += OBJECT_IDENTIFIER_set_single_arc(bp, first_value,
+ fv - first_value, 1);
+ }
+
+ /*
+ * Save the rest of arcs.
+ */
+ for(arcs = ((const char *)arcs) + arc_type_size, i = 2;
+ i < arc_slots;
+ i++, arcs = ((const char *)arcs) + arc_type_size) {
+ bp += OBJECT_IDENTIFIER_set_single_arc(bp,
+ arcs, arc_type_size, 0);
+ }
+
+ assert((unsigned)(bp - buf) <= size);
+
+ /*
+ * Replace buffer.
+ */
+ oid->size = bp - buf;
+ bp = oid->buf;
+ oid->buf = buf;
+ if(bp) FREEMEM(bp);
+
+ return 0;
+}
+
+
+int
+OBJECT_IDENTIFIER_parse_arcs(const char *oid_text, ssize_t oid_txt_length,
+ long *arcs, unsigned int arcs_slots, const char **opt_oid_text_end) {
+ unsigned int arcs_count = 0;
+ const char *oid_end;
+ long value = 0;
+ enum {
+ ST_SKIPSPACE,
+ ST_WAITDIGITS, /* Next character is expected to be a digit */
+ ST_DIGITS
+ } state = ST_SKIPSPACE;
+
+ if(!oid_text || oid_txt_length < -1 || (arcs_slots && !arcs)) {
+ if(opt_oid_text_end) *opt_oid_text_end = oid_text;
+ errno = EINVAL;
+ return -1;
+ }
+
+ if(oid_txt_length == -1)
+ oid_txt_length = strlen(oid_text);
+
+ for(oid_end = oid_text + oid_txt_length; oid_text<oid_end; oid_text++) {
+ switch(*oid_text) {
+ case 0x09: case 0x0a: case 0x0d: case 0x20: /* whitespace */
+ if(state == ST_SKIPSPACE) {
+ continue;
+ } else {
+ break; /* Finish */
+ }
+ case 0x2e: /* '.' */
+ if(state != ST_DIGITS
+ || (oid_text + 1) == oid_end) {
+ state = ST_WAITDIGITS;
+ break;
+ }
+ if(arcs_count < arcs_slots)
+ arcs[arcs_count] = value;
+ arcs_count++;
+ state = ST_WAITDIGITS;
+ continue;
+ case 0x30: case 0x31: case 0x32: case 0x33: case 0x34:
+ case 0x35: case 0x36: case 0x37: case 0x38: case 0x39:
+ if(state != ST_DIGITS) {
+ state = ST_DIGITS;
+ value = 0;
+ }
+ if(1) {
+ long new_value = value * 10;
+ if(new_value / 10 != value
+ || (value = new_value + (*oid_text - 0x30)) < 0) {
+ /* Overflow */
+ state = ST_WAITDIGITS;
+ break;
+ }
+ continue;
+ }
+ default:
+ /* Unexpected symbols */
+ state = ST_WAITDIGITS;
+ break;
+ } /* switch() */
+ break;
+ } /* for() */
+
+
+ if(opt_oid_text_end) *opt_oid_text_end = oid_text;
+
+ /* Finalize last arc */
+ switch(state) {
+ case ST_WAITDIGITS:
+ errno = EINVAL;
+ return -1;
+ case ST_DIGITS:
+ if(arcs_count < arcs_slots)
+ arcs[arcs_count] = value;
+ arcs_count++;
+ /* Fall through */
+ default:
+ return arcs_count;
+ }
+}
+
+
--- /dev/null
+/*-
+ * Copyright (c) 2003, 2004, 2005, 2006 Lev Walkin <vlm@lionet.info>.
+ * All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#include <asn_internal.h>
+#include <OCTET_STRING.h>
+#include <BIT_STRING.h> /* for .bits_unused member */
+#include <errno.h>
+
+/*
+ * OCTET STRING basic type description.
+ */
+static ber_tlv_tag_t asn_DEF_OCTET_STRING_tags[] = {
+ (ASN_TAG_CLASS_UNIVERSAL | (4 << 2))
+};
+static asn_OCTET_STRING_specifics_t asn_DEF_OCTET_STRING_specs = {
+ sizeof(OCTET_STRING_t),
+ offsetof(OCTET_STRING_t, _asn_ctx),
+ 0
+};
+static asn_per_constraint_t asn_DEF_OCTET_STRING_constraint = {
+ APC_SEMI_CONSTRAINED, -1, -1, 0, 0
+};
+asn_TYPE_descriptor_t asn_DEF_OCTET_STRING = {
+ "OCTET STRING", /* Canonical name */
+ "OCTET_STRING", /* XML tag name */
+ OCTET_STRING_free,
+ OCTET_STRING_print, /* non-ascii stuff, generally */
+ asn_generic_no_constraint,
+ OCTET_STRING_decode_ber,
+ OCTET_STRING_encode_der,
+ OCTET_STRING_decode_xer_hex,
+ OCTET_STRING_encode_xer,
+ OCTET_STRING_decode_uper, /* Unaligned PER decoder */
+ OCTET_STRING_encode_uper, /* Unaligned PER encoder */
+ 0, /* Use generic outmost tag fetcher */
+ asn_DEF_OCTET_STRING_tags,
+ sizeof(asn_DEF_OCTET_STRING_tags)
+ / sizeof(asn_DEF_OCTET_STRING_tags[0]),
+ asn_DEF_OCTET_STRING_tags, /* Same as above */
+ sizeof(asn_DEF_OCTET_STRING_tags)
+ / sizeof(asn_DEF_OCTET_STRING_tags[0]),
+ 0, /* No PER visible constraints */
+ 0, 0, /* No members */
+ &asn_DEF_OCTET_STRING_specs
+};
+
+#undef _CH_PHASE
+#undef NEXT_PHASE
+#undef PREV_PHASE
+#define _CH_PHASE(ctx, inc) do { \
+ if(ctx->phase == 0) \
+ ctx->context = 0; \
+ ctx->phase += inc; \
+ } while(0)
+#define NEXT_PHASE(ctx) _CH_PHASE(ctx, +1)
+#define PREV_PHASE(ctx) _CH_PHASE(ctx, -1)
+
+#undef ADVANCE
+#define ADVANCE(num_bytes) do { \
+ size_t num = (num_bytes); \
+ buf_ptr = ((const char *)buf_ptr) + num; \
+ size -= num; \
+ consumed_myself += num; \
+ } while(0)
+
+#undef RETURN
+#define RETURN(_code) do { \
+ asn_dec_rval_t tmprval; \
+ tmprval.code = _code; \
+ tmprval.consumed = consumed_myself; \
+ return tmprval; \
+ } while(0)
+
+#undef APPEND
+#define APPEND(bufptr, bufsize) do { \
+ size_t _bs = (bufsize); /* Append size */ \
+ size_t _ns = ctx->context; /* Allocated now */ \
+ size_t _es = st->size + _bs; /* Expected size */ \
+ /* int is really a typeof(st->size): */ \
+ if((int)_es < 0) RETURN(RC_FAIL); \
+ if(_ns <= _es) { \
+ void *ptr; \
+ /* Be nice and round to the memory allocator */ \
+ do { _ns = _ns ? _ns << 1 : 16; } \
+ while(_ns <= _es); \
+ /* int is really a typeof(st->size): */ \
+ if((int)_ns < 0) RETURN(RC_FAIL); \
+ ptr = REALLOC(st->buf, _ns); \
+ if(ptr) { \
+ st->buf = (uint8_t *)ptr; \
+ ctx->context = _ns; \
+ } else { \
+ RETURN(RC_FAIL); \
+ } \
+ ASN_DEBUG("Reallocating into %ld", (long)_ns); \
+ } \
+ memcpy(st->buf + st->size, bufptr, _bs); \
+ /* Convenient nul-termination */ \
+ st->buf[_es] = '\0'; \
+ st->size = _es; \
+ } while(0)
+
+/*
+ * Internal variant of the OCTET STRING.
+ */
+typedef enum OS_type {
+ _TT_GENERIC = 0, /* Just a random OCTET STRING */
+ _TT_BIT_STRING = 1, /* BIT STRING type, a special case */
+ _TT_ANY = 2 /* ANY type, a special case too */
+} OS_type_e;
+
+/*
+ * The main reason why ASN.1 is still alive is that too much time and effort
+ * is necessary for learning it more or less adequately, thus creating a gut
+ * necessity to demonstrate that aquired skill everywhere afterwards.
+ * No, I am not going to explain what the following stuff is.
+ */
+struct _stack_el {
+ ber_tlv_len_t left; /* What's left to read (or -1) */
+ ber_tlv_len_t got; /* What was actually processed */
+ int cont_level; /* Depth of subcontainment */
+ int want_nulls; /* Want null "end of content" octets? */
+ int bits_chopped; /* Flag in BIT STRING mode */
+ ber_tlv_tag_t tag; /* For debugging purposes */
+ struct _stack_el *prev;
+ struct _stack_el *next;
+};
+struct _stack {
+ struct _stack_el *tail;
+ struct _stack_el *cur_ptr;
+};
+
+static struct _stack_el *
+OS__add_stack_el(struct _stack *st) {
+ struct _stack_el *nel;
+
+ /*
+ * Reuse the old stack frame or allocate a new one.
+ */
+ if(st->cur_ptr && st->cur_ptr->next) {
+ nel = st->cur_ptr->next;
+ nel->bits_chopped = 0;
+ nel->got = 0;
+ /* Retain the nel->cont_level, it's correct. */
+ } else {
+ nel = (struct _stack_el *)CALLOC(1, sizeof(struct _stack_el));
+ if(nel == NULL)
+ return NULL;
+
+ if(st->tail) {
+ /* Increase a subcontainment depth */
+ nel->cont_level = st->tail->cont_level + 1;
+ st->tail->next = nel;
+ }
+ nel->prev = st->tail;
+ st->tail = nel;
+ }
+
+ st->cur_ptr = nel;
+
+ return nel;
+}
+
+static struct _stack *
+_new_stack() {
+ return (struct _stack *)CALLOC(1, sizeof(struct _stack));
+}
+
+/*
+ * Decode OCTET STRING type.
+ */
+asn_dec_rval_t
+OCTET_STRING_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
+ asn_TYPE_descriptor_t *td,
+ void **sptr, const void *buf_ptr, size_t size, int tag_mode) {
+ asn_OCTET_STRING_specifics_t *specs = td->specifics
+ ? (asn_OCTET_STRING_specifics_t *)td->specifics
+ : &asn_DEF_OCTET_STRING_specs;
+ BIT_STRING_t *st = (BIT_STRING_t *)*sptr;
+ asn_dec_rval_t rval;
+ asn_struct_ctx_t *ctx;
+ ssize_t consumed_myself = 0;
+ struct _stack *stck; /* Expectations stack structure */
+ struct _stack_el *sel = 0; /* Stack element */
+ int tlv_constr;
+ OS_type_e type_variant = (OS_type_e)specs->subvariant;
+
+ ASN_DEBUG("Decoding %s as %s (frame %ld)",
+ td->name,
+ (type_variant == _TT_GENERIC) ?
+ "OCTET STRING" : "OS-SpecialCase",
+ (long)size);
+
+ /*
+ * Create the string if does not exist.
+ */
+ if(st == NULL) {
+ st = (BIT_STRING_t *)(*sptr = CALLOC(1, specs->struct_size));
+ if(st == NULL) RETURN(RC_FAIL);
+ }
+
+ /* Restore parsing context */
+ ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset);
+
+ switch(ctx->phase) {
+ case 0:
+ /*
+ * Check tags.
+ */
+ rval = ber_check_tags(opt_codec_ctx, td, ctx,
+ buf_ptr, size, tag_mode, -1,
+ &ctx->left, &tlv_constr);
+ if(rval.code != RC_OK)
+ return rval;
+
+ if(tlv_constr) {
+ /*
+ * Complex operation, requires stack of expectations.
+ */
+ ctx->ptr = _new_stack();
+ if(ctx->ptr) {
+ stck = (struct _stack *)ctx->ptr;
+ } else {
+ RETURN(RC_FAIL);
+ }
+ } else {
+ /*
+ * Jump into stackless primitive decoding.
+ */
+ _CH_PHASE(ctx, 3);
+ if(type_variant == _TT_ANY && tag_mode != 1)
+ APPEND(buf_ptr, rval.consumed);
+ ADVANCE(rval.consumed);
+ goto phase3;
+ }
+
+ NEXT_PHASE(ctx);
+ /* Fall through */
+ case 1:
+ phase1:
+ /*
+ * Fill the stack with expectations.
+ */
+ stck = (struct _stack *)ctx->ptr;
+ sel = stck->cur_ptr;
+ do {
+ ber_tlv_tag_t tlv_tag;
+ ber_tlv_len_t tlv_len;
+ ber_tlv_tag_t expected_tag;
+ ssize_t tl, ll, tlvl;
+ /* This one works even if (sel->left == -1) */
+ ssize_t Left = ((!sel||(size_t)sel->left >= size)
+ ?(ssize_t)size:sel->left);
+
+
+ ASN_DEBUG("%p, s->l=%ld, s->wn=%ld, s->g=%ld\n", sel,
+ (long)(sel?sel->left:0),
+ (long)(sel?sel->want_nulls:0),
+ (long)(sel?sel->got:0)
+ );
+ if(sel && sel->left <= 0 && sel->want_nulls == 0) {
+ if(sel->prev) {
+ struct _stack_el *prev = sel->prev;
+ if(prev->left != -1) {
+ if(prev->left < sel->got)
+ RETURN(RC_FAIL);
+ prev->left -= sel->got;
+ }
+ prev->got += sel->got;
+ sel = stck->cur_ptr = prev;
+ if(!sel) break;
+ tlv_constr = 1;
+ continue;
+ } else {
+ sel = stck->cur_ptr = 0;
+ break; /* Nothing to wait */
+ }
+ }
+
+ tl = ber_fetch_tag(buf_ptr, Left, &tlv_tag);
+ ASN_DEBUG("fetch tag(size=%ld,L=%ld), %sstack, left=%ld, wn=%ld, tl=%ld",
+ (long)size, (long)Left, sel?"":"!",
+ (long)(sel?sel->left:0),
+ (long)(sel?sel->want_nulls:0),
+ (long)tl);
+ switch(tl) {
+ case -1: RETURN(RC_FAIL);
+ case 0: RETURN(RC_WMORE);
+ }
+
+ tlv_constr = BER_TLV_CONSTRUCTED(buf_ptr);
+
+ ll = ber_fetch_length(tlv_constr,
+ (const char *)buf_ptr + tl,Left - tl,&tlv_len);
+ ASN_DEBUG("Got tag=%s, tc=%d, left=%ld, tl=%ld, len=%ld, ll=%ld",
+ ber_tlv_tag_string(tlv_tag), tlv_constr,
+ (long)Left, (long)tl, (long)tlv_len, (long)ll);
+ switch(ll) {
+ case -1: RETURN(RC_FAIL);
+ case 0: RETURN(RC_WMORE);
+ }
+
+ if(sel && sel->want_nulls
+ && ((const uint8_t *)buf_ptr)[0] == 0
+ && ((const uint8_t *)buf_ptr)[1] == 0)
+ {
+
+ ASN_DEBUG("Eat EOC; wn=%d--", sel->want_nulls);
+
+ if(type_variant == _TT_ANY
+ && (tag_mode != 1 || sel->cont_level))
+ APPEND("\0\0", 2);
+
+ ADVANCE(2);
+ sel->got += 2;
+ if(sel->left != -1) {
+ sel->left -= 2; /* assert(sel->left >= 2) */
+ }
+
+ sel->want_nulls--;
+ if(sel->want_nulls == 0) {
+ /* Move to the next expectation */
+ sel->left = 0;
+ tlv_constr = 1;
+ }
+
+ continue;
+ }
+
+ /*
+ * Set up expected tags,
+ * depending on ASN.1 type being decoded.
+ */
+ switch(type_variant) {
+ case _TT_BIT_STRING:
+ /* X.690: 8.6.4.1, NOTE 2 */
+ /* Fall through */
+ case _TT_GENERIC:
+ default:
+ if(sel) {
+ int level = sel->cont_level;
+ if(level < td->all_tags_count) {
+ expected_tag = td->all_tags[level];
+ break;
+ } else if(td->all_tags_count) {
+ expected_tag = td->all_tags
+ [td->all_tags_count - 1];
+ break;
+ }
+ /* else, Fall through */
+ }
+ /* Fall through */
+ case _TT_ANY:
+ expected_tag = tlv_tag;
+ break;
+ }
+
+
+ if(tlv_tag != expected_tag) {
+ char buf[2][32];
+ ber_tlv_tag_snprint(tlv_tag,
+ buf[0], sizeof(buf[0]));
+ ber_tlv_tag_snprint(td->tags[td->tags_count-1],
+ buf[1], sizeof(buf[1]));
+ ASN_DEBUG("Tag does not match expectation: %s != %s",
+ buf[0], buf[1]);
+ RETURN(RC_FAIL);
+ }
+
+ tlvl = tl + ll; /* Combined length of T and L encoding */
+ if((tlv_len + tlvl) < 0) {
+ /* tlv_len value is too big */
+ ASN_DEBUG("TLV encoding + length (%ld) is too big",
+ (long)tlv_len);
+ RETURN(RC_FAIL);
+ }
+
+ /*
+ * Append a new expectation.
+ */
+ sel = OS__add_stack_el(stck);
+ if(!sel) RETURN(RC_FAIL);
+
+ sel->tag = tlv_tag;
+
+ sel->want_nulls = (tlv_len==-1);
+ if(sel->prev && sel->prev->left != -1) {
+ /* Check that the parent frame is big enough */
+ if(sel->prev->left < tlvl + (tlv_len==-1?0:tlv_len))
+ RETURN(RC_FAIL);
+ if(tlv_len == -1)
+ sel->left = sel->prev->left - tlvl;
+ else
+ sel->left = tlv_len;
+ } else {
+ sel->left = tlv_len;
+ }
+ if(type_variant == _TT_ANY
+ && (tag_mode != 1 || sel->cont_level))
+ APPEND(buf_ptr, tlvl);
+ sel->got += tlvl;
+ ADVANCE(tlvl);
+
+ ASN_DEBUG("+EXPECT2 got=%ld left=%ld, wn=%d, clvl=%d",
+ (long)sel->got, (long)sel->left,
+ sel->want_nulls, sel->cont_level);
+
+ } while(tlv_constr);
+ if(sel == NULL) {
+ /* Finished operation, "phase out" */
+ ASN_DEBUG("Phase out");
+ _CH_PHASE(ctx, +3);
+ break;
+ }
+
+ NEXT_PHASE(ctx);
+ /* Fall through */
+ case 2:
+ stck = (struct _stack *)ctx->ptr;
+ sel = stck->cur_ptr;
+ ASN_DEBUG("Phase 2: Need %ld bytes, size=%ld, alrg=%ld, wn=%d",
+ (long)sel->left, (long)size, (long)sel->got,
+ sel->want_nulls);
+ {
+ ber_tlv_len_t len;
+
+ assert(sel->left >= 0);
+
+ len = ((ber_tlv_len_t)size < sel->left)
+ ? (ber_tlv_len_t)size : sel->left;
+ if(len > 0) {
+ if(type_variant == _TT_BIT_STRING
+ && sel->bits_chopped == 0) {
+ /* Put the unused-bits-octet away */
+ st->bits_unused = *(const uint8_t *)buf_ptr;
+ APPEND(((const char *)buf_ptr+1), (len - 1));
+ sel->bits_chopped = 1;
+ } else {
+ APPEND(buf_ptr, len);
+ }
+ ADVANCE(len);
+ sel->left -= len;
+ sel->got += len;
+ }
+
+ if(sel->left) {
+ ASN_DEBUG("OS left %ld, size = %ld, wn=%d\n",
+ (long)sel->left, (long)size, sel->want_nulls);
+ RETURN(RC_WMORE);
+ }
+
+ PREV_PHASE(ctx);
+ goto phase1;
+ }
+ break;
+ case 3:
+ phase3:
+ /*
+ * Primitive form, no stack required.
+ */
+ assert(ctx->left >= 0);
+
+ if(size < (size_t)ctx->left) {
+ if(!size) RETURN(RC_WMORE);
+ if(type_variant == _TT_BIT_STRING && !ctx->context) {
+ st->bits_unused = *(const uint8_t *)buf_ptr;
+ ctx->left--;
+ ADVANCE(1);
+ }
+ APPEND(buf_ptr, size);
+ assert(ctx->context > 0);
+ ctx->left -= size;
+ ADVANCE(size);
+ RETURN(RC_WMORE);
+ } else {
+ if(type_variant == _TT_BIT_STRING
+ && !ctx->context && ctx->left) {
+ st->bits_unused = *(const uint8_t *)buf_ptr;
+ ctx->left--;
+ ADVANCE(1);
+ }
+ APPEND(buf_ptr, ctx->left);
+ ADVANCE(ctx->left);
+ ctx->left = 0;
+
+ NEXT_PHASE(ctx);
+ }
+ break;
+ }
+
+ if(sel) {
+ ASN_DEBUG("3sel p=%p, wn=%d, l=%ld, g=%ld, size=%ld",
+ sel->prev, sel->want_nulls,
+ (long)sel->left, (long)sel->got, (long)size);
+ if(sel->prev || sel->want_nulls > 1 || sel->left > 0) {
+ RETURN(RC_WMORE);
+ }
+ }
+
+ /*
+ * BIT STRING-specific processing.
+ */
+ if(type_variant == _TT_BIT_STRING && st->size) {
+ /* Finalize BIT STRING: zero out unused bits. */
+ st->buf[st->size-1] &= 0xff << st->bits_unused;
+ }
+
+ ASN_DEBUG("Took %ld bytes to encode %s: [%s]:%ld",
+ (long)consumed_myself, td->name,
+ (type_variant == _TT_GENERIC) ? (char *)st->buf : "<data>",
+ (long)st->size);
+
+
+ RETURN(RC_OK);
+}
+
+/*
+ * Encode OCTET STRING type using DER.
+ */
+asn_enc_rval_t
+OCTET_STRING_encode_der(asn_TYPE_descriptor_t *td, void *sptr,
+ int tag_mode, ber_tlv_tag_t tag,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ asn_enc_rval_t er;
+ asn_OCTET_STRING_specifics_t *specs = td->specifics
+ ? (asn_OCTET_STRING_specifics_t *)td->specifics
+ : &asn_DEF_OCTET_STRING_specs;
+ BIT_STRING_t *st = (BIT_STRING_t *)sptr;
+ OS_type_e type_variant = (OS_type_e)specs->subvariant;
+ int fix_last_byte = 0;
+
+ ASN_DEBUG("%s %s as OCTET STRING",
+ cb?"Estimating":"Encoding", td->name);
+
+ /*
+ * Write tags.
+ */
+ if(type_variant != _TT_ANY || tag_mode == 1) {
+ er.encoded = der_write_tags(td,
+ (type_variant == _TT_BIT_STRING) + st->size,
+ tag_mode, type_variant == _TT_ANY, tag, cb, app_key);
+ if(er.encoded == -1) {
+ er.failed_type = td;
+ er.structure_ptr = sptr;
+ return er;
+ }
+ } else {
+ /* Disallow: [<tag>] IMPLICIT ANY */
+ assert(type_variant != _TT_ANY || tag_mode != -1);
+ er.encoded = 0;
+ }
+
+ if(!cb) {
+ er.encoded += (type_variant == _TT_BIT_STRING) + st->size;
+ _ASN_ENCODED_OK(er);
+ }
+
+ /*
+ * Prepare to deal with the last octet of BIT STRING.
+ */
+ if(type_variant == _TT_BIT_STRING) {
+ uint8_t b = st->bits_unused & 0x07;
+ if(b && st->size) fix_last_byte = 1;
+ _ASN_CALLBACK(&b, 1);
+ er.encoded++;
+ }
+
+ /* Invoke callback for the main part of the buffer */
+ _ASN_CALLBACK(st->buf, st->size - fix_last_byte);
+
+ /* The last octet should be stripped off the unused bits */
+ if(fix_last_byte) {
+ uint8_t b = st->buf[st->size-1] & (0xff << st->bits_unused);
+ _ASN_CALLBACK(&b, 1);
+ }
+
+ er.encoded += st->size;
+ _ASN_ENCODED_OK(er);
+cb_failed:
+ _ASN_ENCODE_FAILED;
+}
+
+asn_enc_rval_t
+OCTET_STRING_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ static const char *h2c = "0123456789ABCDEF";
+ const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr;
+ asn_enc_rval_t er;
+ char scratch[16 * 3 + 4];
+ char *p = scratch;
+ uint8_t *buf;
+ uint8_t *end;
+ size_t i;
+
+ if(!st || !st->buf)
+ _ASN_ENCODE_FAILED;
+
+ er.encoded = 0;
+
+ /*
+ * Dump the contents of the buffer in hexadecimal.
+ */
+ buf = st->buf;
+ end = buf + st->size;
+ if(flags & XER_F_CANONICAL) {
+ char *scend = scratch + (sizeof(scratch) - 2);
+ for(; buf < end; buf++) {
+ if(p >= scend) {
+ _ASN_CALLBACK(scratch, p - scratch);
+ er.encoded += p - scratch;
+ p = scratch;
+ }
+ *p++ = h2c[(*buf >> 4) & 0x0F];
+ *p++ = h2c[*buf & 0x0F];
+ }
+
+ _ASN_CALLBACK(scratch, p-scratch); /* Dump the rest */
+ er.encoded += p - scratch;
+ } else {
+ for(i = 0; buf < end; buf++, i++) {
+ if(!(i % 16) && (i || st->size > 16)) {
+ _ASN_CALLBACK(scratch, p-scratch);
+ er.encoded += (p-scratch);
+ p = scratch;
+ _i_ASN_TEXT_INDENT(1, ilevel);
+ }
+ *p++ = h2c[(*buf >> 4) & 0x0F];
+ *p++ = h2c[*buf & 0x0F];
+ *p++ = 0x20;
+ }
+ if(p - scratch) {
+ p--; /* Remove the tail space */
+ _ASN_CALLBACK(scratch, p-scratch); /* Dump the rest */
+ er.encoded += p - scratch;
+ if(st->size > 16)
+ _i_ASN_TEXT_INDENT(1, ilevel-1);
+ }
+ }
+
+ _ASN_ENCODED_OK(er);
+cb_failed:
+ _ASN_ENCODE_FAILED;
+}
+
+static struct OCTET_STRING__xer_escape_table_s {
+ char *string;
+ int size;
+} OCTET_STRING__xer_escape_table[] = {
+#define OSXET(s) { s, sizeof(s) - 1 }
+ OSXET("\074\156\165\154\057\076"), /* <nul/> */
+ OSXET("\074\163\157\150\057\076"), /* <soh/> */
+ OSXET("\074\163\164\170\057\076"), /* <stx/> */
+ OSXET("\074\145\164\170\057\076"), /* <etx/> */
+ OSXET("\074\145\157\164\057\076"), /* <eot/> */
+ OSXET("\074\145\156\161\057\076"), /* <enq/> */
+ OSXET("\074\141\143\153\057\076"), /* <ack/> */
+ OSXET("\074\142\145\154\057\076"), /* <bel/> */
+ OSXET("\074\142\163\057\076"), /* <bs/> */
+ OSXET("\011"), /* \t */
+ OSXET("\012"), /* \n */
+ OSXET("\074\166\164\057\076"), /* <vt/> */
+ OSXET("\074\146\146\057\076"), /* <ff/> */
+ OSXET("\015"), /* \r */
+ OSXET("\074\163\157\057\076"), /* <so/> */
+ OSXET("\074\163\151\057\076"), /* <si/> */
+ OSXET("\074\144\154\145\057\076"), /* <dle/> */
+ OSXET("\074\144\143\061\057\076"), /* <de1/> */
+ OSXET("\074\144\143\062\057\076"), /* <de2/> */
+ OSXET("\074\144\143\063\057\076"), /* <de3/> */
+ OSXET("\074\144\143\064\057\076"), /* <de4/> */
+ OSXET("\074\156\141\153\057\076"), /* <nak/> */
+ OSXET("\074\163\171\156\057\076"), /* <syn/> */
+ OSXET("\074\145\164\142\057\076"), /* <etb/> */
+ OSXET("\074\143\141\156\057\076"), /* <can/> */
+ OSXET("\074\145\155\057\076"), /* <em/> */
+ OSXET("\074\163\165\142\057\076"), /* <sub/> */
+ OSXET("\074\145\163\143\057\076"), /* <esc/> */
+ OSXET("\074\151\163\064\057\076"), /* <is4/> */
+ OSXET("\074\151\163\063\057\076"), /* <is3/> */
+ OSXET("\074\151\163\062\057\076"), /* <is2/> */
+ OSXET("\074\151\163\061\057\076"), /* <is1/> */
+ { 0, 0 }, /* " " */
+ { 0, 0 }, /* ! */
+ { 0, 0 }, /* \" */
+ { 0, 0 }, /* # */
+ { 0, 0 }, /* $ */
+ { 0, 0 }, /* % */
+ OSXET("\046\141\155\160\073"), /* & */
+ { 0, 0 }, /* ' */
+ {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, /* ()*+,-./ */
+ {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, /* 01234567 */
+ {0,0},{0,0},{0,0},{0,0}, /* 89:; */
+ OSXET("\046\154\164\073"), /* < */
+ { 0, 0 }, /* = */
+ OSXET("\046\147\164\073"), /* > */
+};
+
+static int
+OS__check_escaped_control_char(const void *buf, int size) {
+ size_t i;
+ /*
+ * Inefficient algorithm which translates the escape sequences
+ * defined above into characters. Returns -1 if not found.
+ * TODO: replace by a faster algorithm (bsearch(), hash or
+ * nested table lookups).
+ */
+ for(i = 0; i < 32 /* Don't spend time on the bottom half */; i++) {
+ struct OCTET_STRING__xer_escape_table_s *el;
+ el = &OCTET_STRING__xer_escape_table[i];
+ if(el->size == size && memcmp(buf, el->string, size) == 0)
+ return i;
+ }
+ return -1;
+}
+
+static int
+OCTET_STRING__handle_control_chars(void *struct_ptr, const void *chunk_buf, size_t chunk_size) {
+ /*
+ * This might be one of the escape sequences
+ * for control characters. Check it out.
+ * #11.15.5
+ */
+ int control_char = OS__check_escaped_control_char(chunk_buf,chunk_size);
+ if(control_char >= 0) {
+ OCTET_STRING_t *st = (OCTET_STRING_t *)struct_ptr;
+ void *p = REALLOC(st->buf, st->size + 2);
+ if(p) {
+ st->buf = (uint8_t *)p;
+ st->buf[st->size++] = control_char;
+ st->buf[st->size] = '\0'; /* nul-termination */
+ return 0;
+ }
+ }
+
+ return -1; /* No, it's not */
+}
+
+asn_enc_rval_t
+OCTET_STRING_encode_xer_utf8(asn_TYPE_descriptor_t *td, void *sptr,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr;
+ asn_enc_rval_t er;
+ uint8_t *buf, *end;
+ uint8_t *ss; /* Sequence start */
+ ssize_t encoded_len = 0;
+
+ (void)ilevel; /* Unused argument */
+ (void)flags; /* Unused argument */
+
+ if(!st || !st->buf)
+ _ASN_ENCODE_FAILED;
+
+ buf = st->buf;
+ end = buf + st->size;
+ for(ss = buf; buf < end; buf++) {
+ unsigned int ch = *buf;
+ int s_len; /* Special encoding sequence length */
+
+ /*
+ * Escape certain characters: X.680/11.15
+ */
+ if(ch < sizeof(OCTET_STRING__xer_escape_table)
+ /sizeof(OCTET_STRING__xer_escape_table[0])
+ && (s_len = OCTET_STRING__xer_escape_table[ch].size)) {
+ if(((buf - ss) && cb(ss, buf - ss, app_key) < 0)
+ || cb(OCTET_STRING__xer_escape_table[ch].string, s_len,
+ app_key) < 0)
+ _ASN_ENCODE_FAILED;
+ encoded_len += (buf - ss) + s_len;
+ ss = buf + 1;
+ }
+ }
+
+ encoded_len += (buf - ss);
+ if((buf - ss) && cb(ss, buf - ss, app_key) < 0)
+ _ASN_ENCODE_FAILED;
+
+ er.encoded = encoded_len;
+ _ASN_ENCODED_OK(er);
+}
+
+/*
+ * Convert from hexadecimal format (cstring): "AB CD EF"
+ */
+static ssize_t OCTET_STRING__convert_hexadecimal(void *sptr, const void *chunk_buf, size_t chunk_size, int have_more) {
+ OCTET_STRING_t *st = (OCTET_STRING_t *)sptr;
+ const char *chunk_stop = (const char *)chunk_buf;
+ const char *p = chunk_stop;
+ const char *pend = p + chunk_size;
+ unsigned int clv = 0;
+ int half = 0; /* Half bit */
+ uint8_t *buf;
+
+ /* Reallocate buffer according to high cap estimation */
+ ssize_t _ns = st->size + (chunk_size + 1) / 2;
+ void *nptr = REALLOC(st->buf, _ns + 1);
+ if(!nptr) return -1;
+ st->buf = (uint8_t *)nptr;
+ buf = st->buf + st->size;
+
+ /*
+ * If something like " a b c " appears here, the " a b":3 will be
+ * converted, and the rest skipped. That is, unless buf_size is greater
+ * than chunk_size, then it'll be equivalent to "ABC0".
+ */
+ for(; p < pend; p++) {
+ int ch = *(const unsigned char *)p;
+ switch(ch) {
+ case 0x09: case 0x0a: case 0x0c: case 0x0d:
+ case 0x20:
+ /* Ignore whitespace */
+ continue;
+ case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: /*01234*/
+ case 0x35: case 0x36: case 0x37: case 0x38: case 0x39: /*56789*/
+ clv = (clv << 4) + (ch - 0x30);
+ break;
+ case 0x41: case 0x42: case 0x43: /* ABC */
+ case 0x44: case 0x45: case 0x46: /* DEF */
+ clv = (clv << 4) + (ch - 0x41 + 10);
+ break;
+ case 0x61: case 0x62: case 0x63: /* abc */
+ case 0x64: case 0x65: case 0x66: /* def */
+ clv = (clv << 4) + (ch - 0x61 + 10);
+ break;
+ default:
+ *buf = 0; /* JIC */
+ return -1;
+ }
+ if(half++) {
+ half = 0;
+ *buf++ = clv;
+ chunk_stop = p + 1;
+ }
+ }
+
+ /*
+ * Check partial decoding.
+ */
+ if(half) {
+ if(have_more) {
+ /*
+ * Partial specification is fine,
+ * because no more more PXER_TEXT data is available.
+ */
+ *buf++ = clv << 4;
+ chunk_stop = p;
+ }
+ } else {
+ chunk_stop = p;
+ }
+
+ st->size = buf - st->buf; /* Adjust the buffer size */
+ assert(st->size <= _ns);
+ st->buf[st->size] = 0; /* Courtesy termination */
+
+ return (chunk_stop - (const char *)chunk_buf); /* Converted size */
+}
+
+/*
+ * Convert from binary format: "00101011101"
+ */
+static ssize_t OCTET_STRING__convert_binary(void *sptr, const void *chunk_buf, size_t chunk_size, int have_more) {
+ BIT_STRING_t *st = (BIT_STRING_t *)sptr;
+ const char *p = (const char *)chunk_buf;
+ const char *pend = p + chunk_size;
+ int bits_unused = st->bits_unused & 0x7;
+ uint8_t *buf;
+
+ /* Reallocate buffer according to high cap estimation */
+ ssize_t _ns = st->size + (chunk_size + 7) / 8;
+ void *nptr = REALLOC(st->buf, _ns + 1);
+ if(!nptr) return -1;
+ st->buf = (uint8_t *)nptr;
+ buf = st->buf + st->size;
+
+ (void)have_more;
+
+ if(bits_unused == 0)
+ bits_unused = 8;
+ else if(st->size)
+ buf--;
+
+ /*
+ * Convert series of 0 and 1 into the octet string.
+ */
+ for(; p < pend; p++) {
+ int ch = *(const unsigned char *)p;
+ switch(ch) {
+ case 0x09: case 0x0a: case 0x0c: case 0x0d:
+ case 0x20:
+ /* Ignore whitespace */
+ break;
+ case 0x30:
+ case 0x31:
+ if(bits_unused-- <= 0) {
+ *++buf = 0; /* Clean the cell */
+ bits_unused = 7;
+ }
+ *buf |= (ch&1) << bits_unused;
+ break;
+ default:
+ st->bits_unused = bits_unused;
+ return -1;
+ }
+ }
+
+ if(bits_unused == 8) {
+ st->size = buf - st->buf;
+ st->bits_unused = 0;
+ } else {
+ st->size = buf - st->buf + 1;
+ st->bits_unused = bits_unused;
+ }
+
+ assert(st->size <= _ns);
+ st->buf[st->size] = 0; /* Courtesy termination */
+
+ return chunk_size; /* Converted in full */
+}
+
+/*
+ * Something like strtod(), but with stricter rules.
+ */
+static int
+OS__strtoent(int base, const char *buf, const char *end, int32_t *ret_value) {
+ int32_t val = 0;
+ const char *p;
+
+ for(p = buf; p < end; p++) {
+ int ch = *p;
+
+ /* Strange huge value */
+ if((val * base + base) < 0)
+ return -1;
+
+ switch(ch) {
+ case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: /*01234*/
+ case 0x35: case 0x36: case 0x37: case 0x38: case 0x39: /*56789*/
+ val = val * base + (ch - 0x30);
+ break;
+ case 0x41: case 0x42: case 0x43: /* ABC */
+ case 0x44: case 0x45: case 0x46: /* DEF */
+ val = val * base + (ch - 0x41 + 10);
+ break;
+ case 0x61: case 0x62: case 0x63: /* abc */
+ case 0x64: case 0x65: case 0x66: /* def */
+ val = val * base + (ch - 0x61 + 10);
+ break;
+ case 0x3b: /* ';' */
+ *ret_value = val;
+ return (p - buf) + 1;
+ default:
+ return -1; /* Character set error */
+ }
+ }
+
+ *ret_value = -1;
+ return (p - buf);
+}
+
+/*
+ * Convert from the plain UTF-8 format, expanding entity references: "2 < 3"
+ */
+static ssize_t OCTET_STRING__convert_entrefs(void *sptr, const void *chunk_buf, size_t chunk_size, int have_more) {
+ OCTET_STRING_t *st = (OCTET_STRING_t *)sptr;
+ const char *p = (const char *)chunk_buf;
+ const char *pend = p + chunk_size;
+ uint8_t *buf;
+
+ /* Reallocate buffer */
+ ssize_t _ns = st->size + chunk_size;
+ void *nptr = REALLOC(st->buf, _ns + 1);
+ if(!nptr) return -1;
+ st->buf = (uint8_t *)nptr;
+ buf = st->buf + st->size;
+
+ /*
+ * Convert series of 0 and 1 into the octet string.
+ */
+ for(; p < pend; p++) {
+ int ch = *(const unsigned char *)p;
+ int len; /* Length of the rest of the chunk */
+
+ if(ch != 0x26 /* '&' */) {
+ *buf++ = ch;
+ continue; /* That was easy... */
+ }
+
+ /*
+ * Process entity reference.
+ */
+ len = chunk_size - (p - (const char *)chunk_buf);
+ if(len == 1 /* "&" */) goto want_more;
+ if(p[1] == 0x23 /* '#' */) {
+ const char *pval; /* Pointer to start of digits */
+ int32_t val = 0; /* Entity reference value */
+ int base;
+
+ if(len == 2 /* "&#" */) goto want_more;
+ if(p[2] == 0x78 /* 'x' */)
+ pval = p + 3, base = 16;
+ else
+ pval = p + 2, base = 10;
+ len = OS__strtoent(base, pval, p + len, &val);
+ if(len == -1) {
+ /* Invalid charset. Just copy verbatim. */
+ *buf++ = ch;
+ continue;
+ }
+ if(!len || pval[len-1] != 0x3b) goto want_more;
+ assert(val > 0);
+ p += (pval - p) + len - 1; /* Advance past entref */
+
+ if(val < 0x80) {
+ *buf++ = (char)val;
+ } else if(val < 0x800) {
+ *buf++ = 0xc0 | ((val >> 6));
+ *buf++ = 0x80 | ((val & 0x3f));
+ } else if(val < 0x10000) {
+ *buf++ = 0xe0 | ((val >> 12));
+ *buf++ = 0x80 | ((val >> 6) & 0x3f);
+ *buf++ = 0x80 | ((val & 0x3f));
+ } else if(val < 0x200000) {
+ *buf++ = 0xf0 | ((val >> 18));
+ *buf++ = 0x80 | ((val >> 12) & 0x3f);
+ *buf++ = 0x80 | ((val >> 6) & 0x3f);
+ *buf++ = 0x80 | ((val & 0x3f));
+ } else if(val < 0x4000000) {
+ *buf++ = 0xf8 | ((val >> 24));
+ *buf++ = 0x80 | ((val >> 18) & 0x3f);
+ *buf++ = 0x80 | ((val >> 12) & 0x3f);
+ *buf++ = 0x80 | ((val >> 6) & 0x3f);
+ *buf++ = 0x80 | ((val & 0x3f));
+ } else {
+ *buf++ = 0xfc | ((val >> 30) & 0x1);
+ *buf++ = 0x80 | ((val >> 24) & 0x3f);
+ *buf++ = 0x80 | ((val >> 18) & 0x3f);
+ *buf++ = 0x80 | ((val >> 12) & 0x3f);
+ *buf++ = 0x80 | ((val >> 6) & 0x3f);
+ *buf++ = 0x80 | ((val & 0x3f));
+ }
+ } else {
+ /*
+ * Ugly, limited parsing of & > <
+ */
+ char *sc = (char *)memchr(p, 0x3b, len > 5 ? 5 : len);
+ if(!sc) goto want_more;
+ if((sc - p) == 4
+ && p[1] == 0x61 /* 'a' */
+ && p[2] == 0x6d /* 'm' */
+ && p[3] == 0x70 /* 'p' */) {
+ *buf++ = 0x26;
+ p = sc;
+ continue;
+ }
+ if((sc - p) == 3) {
+ if(p[1] == 0x6c) {
+ *buf = 0x3c; /* '<' */
+ } else if(p[1] == 0x67) {
+ *buf = 0x3e; /* '>' */
+ } else {
+ /* Unsupported entity reference */
+ *buf++ = ch;
+ continue;
+ }
+ if(p[2] != 0x74) {
+ /* Unsupported entity reference */
+ *buf++ = ch;
+ continue;
+ }
+ buf++;
+ p = sc;
+ continue;
+ }
+ /* Unsupported entity reference */
+ *buf++ = ch;
+ }
+
+ continue;
+ want_more:
+ if(have_more) {
+ /*
+ * We know that no more data (of the same type)
+ * is coming. Copy the rest verbatim.
+ */
+ *buf++ = ch;
+ continue;
+ }
+ chunk_size = (p - (const char *)chunk_buf);
+ /* Processing stalled: need more data */
+ break;
+ }
+
+ st->size = buf - st->buf;
+ assert(st->size <= _ns);
+ st->buf[st->size] = 0; /* Courtesy termination */
+
+ return chunk_size; /* Converted in full */
+}
+
+/*
+ * Decode OCTET STRING from the XML element's body.
+ */
+static asn_dec_rval_t
+OCTET_STRING__decode_xer(asn_codec_ctx_t *opt_codec_ctx,
+ asn_TYPE_descriptor_t *td, void **sptr,
+ const char *opt_mname, const void *buf_ptr, size_t size,
+ int (*opt_unexpected_tag_decoder)
+ (void *struct_ptr, const void *chunk_buf, size_t chunk_size),
+ ssize_t (*body_receiver)
+ (void *struct_ptr, const void *chunk_buf, size_t chunk_size,
+ int have_more)
+) {
+ OCTET_STRING_t *st = (OCTET_STRING_t *)*sptr;
+ asn_OCTET_STRING_specifics_t *specs = td->specifics
+ ? (asn_OCTET_STRING_specifics_t *)td->specifics
+ : &asn_DEF_OCTET_STRING_specs;
+ const char *xml_tag = opt_mname ? opt_mname : td->xml_tag;
+ asn_struct_ctx_t *ctx; /* Per-structure parser context */
+ asn_dec_rval_t rval; /* Return value from the decoder */
+ int st_allocated;
+
+ /*
+ * Create the string if does not exist.
+ */
+ if(!st) {
+ st = (OCTET_STRING_t *)CALLOC(1, specs->struct_size);
+ *sptr = (void *)st;
+ if(!st) goto sta_failed;
+ st_allocated = 1;
+ } else {
+ st_allocated = 0;
+ }
+ if(!st->buf) {
+ /* This is separate from above section */
+ st->buf = (uint8_t *)CALLOC(1, 1);
+ if(!st->buf) {
+ if(st_allocated) {
+ *sptr = 0;
+ goto stb_failed;
+ } else {
+ goto sta_failed;
+ }
+ }
+ }
+
+ /* Restore parsing context */
+ ctx = (asn_struct_ctx_t *)(((char *)*sptr) + specs->ctx_offset);
+
+ return xer_decode_general(opt_codec_ctx, ctx, *sptr, xml_tag,
+ buf_ptr, size, opt_unexpected_tag_decoder, body_receiver);
+
+stb_failed:
+ FREEMEM(st);
+sta_failed:
+ rval.code = RC_FAIL;
+ rval.consumed = 0;
+ return rval;
+}
+
+/*
+ * Decode OCTET STRING from the hexadecimal data.
+ */
+asn_dec_rval_t
+OCTET_STRING_decode_xer_hex(asn_codec_ctx_t *opt_codec_ctx,
+ asn_TYPE_descriptor_t *td, void **sptr,
+ const char *opt_mname, const void *buf_ptr, size_t size) {
+ return OCTET_STRING__decode_xer(opt_codec_ctx, td, sptr, opt_mname,
+ buf_ptr, size, 0, OCTET_STRING__convert_hexadecimal);
+}
+
+/*
+ * Decode OCTET STRING from the binary (0/1) data.
+ */
+asn_dec_rval_t
+OCTET_STRING_decode_xer_binary(asn_codec_ctx_t *opt_codec_ctx,
+ asn_TYPE_descriptor_t *td, void **sptr,
+ const char *opt_mname, const void *buf_ptr, size_t size) {
+ return OCTET_STRING__decode_xer(opt_codec_ctx, td, sptr, opt_mname,
+ buf_ptr, size, 0, OCTET_STRING__convert_binary);
+}
+
+/*
+ * Decode OCTET STRING from the string (ASCII/UTF-8) data.
+ */
+asn_dec_rval_t
+OCTET_STRING_decode_xer_utf8(asn_codec_ctx_t *opt_codec_ctx,
+ asn_TYPE_descriptor_t *td, void **sptr,
+ const char *opt_mname, const void *buf_ptr, size_t size) {
+ return OCTET_STRING__decode_xer(opt_codec_ctx, td, sptr, opt_mname,
+ buf_ptr, size,
+ OCTET_STRING__handle_control_chars,
+ OCTET_STRING__convert_entrefs);
+}
+
+asn_dec_rval_t
+OCTET_STRING_decode_uper(asn_codec_ctx_t *opt_codec_ctx,
+ asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints,
+ void **sptr, asn_per_data_t *pd) {
+
+ asn_OCTET_STRING_specifics_t *specs = td->specifics
+ ? (asn_OCTET_STRING_specifics_t *)td->specifics
+ : &asn_DEF_OCTET_STRING_specs;
+ asn_per_constraint_t *ct = constraints ? &constraints->size
+ : (td->per_constraints
+ ? &td->per_constraints->size
+ : &asn_DEF_OCTET_STRING_constraint);
+ asn_dec_rval_t rval = { RC_OK, 0 };
+ BIT_STRING_t *st = (BIT_STRING_t *)*sptr;
+ ssize_t consumed_myself = 0;
+ int repeat;
+ int unit_bits = (specs->subvariant != 1) * 7 + 1;
+
+ (void)opt_codec_ctx;
+
+ /*
+ * Allocate the string.
+ */
+ if(!st) {
+ st = (BIT_STRING_t *)(*sptr = CALLOC(1, specs->struct_size));
+ if(!st) RETURN(RC_FAIL);
+ }
+
+ ASN_DEBUG("PER Decoding %s %ld .. %ld bits %d",
+ ct->flags & APC_EXTENSIBLE ? "extensible" : "fixed",
+ ct->lower_bound, ct->upper_bound, ct->effective_bits);
+
+ if(ct->flags & APC_EXTENSIBLE) {
+ int inext = per_get_few_bits(pd, 1);
+ if(inext < 0) RETURN(RC_WMORE);
+ if(inext) ct = &asn_DEF_OCTET_STRING_constraint;
+ consumed_myself = 0;
+ }
+
+ if(ct->effective_bits >= 0
+ && (!st->buf || st->size < ct->upper_bound)) {
+ FREEMEM(st->buf);
+ if(unit_bits == 1) {
+ st->size = (ct->upper_bound + 7) >> 3;
+ } else {
+ st->size = ct->upper_bound;
+ }
+ st->buf = (uint8_t *)MALLOC(st->size + 1);
+ if(!st->buf) { st->size = 0; RETURN(RC_FAIL); }
+ }
+
+ /* X.691, #16.5: zero-length encoding */
+ /* X.691, #16.6: short fixed length encoding (up to 2 octets) */
+ /* X.691, #16.7: long fixed length encoding (up to 64K octets) */
+ if(ct->effective_bits == 0) {
+ int ret = per_get_many_bits(pd, st->buf, 0,
+ unit_bits * ct->upper_bound);
+ if(ret < 0) RETURN(RC_WMORE);
+ consumed_myself += unit_bits * ct->upper_bound;
+ st->buf[st->size] = 0;
+ if(unit_bits == 1 && (ct->upper_bound & 0x7))
+ st->bits_unused = 8 - (ct->upper_bound & 0x7);
+ RETURN(RC_OK);
+ }
+
+ st->size = 0;
+ do {
+ ssize_t len_bytes;
+ ssize_t len_bits;
+ void *p;
+ int ret;
+
+ /* Get the PER length */
+ len_bits = uper_get_length(pd, ct->effective_bits, &repeat);
+ if(len_bits < 0) RETURN(RC_WMORE);
+ len_bits += ct->lower_bound;
+
+ ASN_DEBUG("Got PER length eb %ld, len %ld, %s (%s)",
+ (long)ct->effective_bits, (long)len_bits,
+ repeat ? "repeat" : "once", td->name);
+ if(unit_bits == 1) {
+ len_bytes = (len_bits + 7) >> 3;
+ if(len_bits & 0x7)
+ st->bits_unused = 8 - (len_bits & 0x7);
+ /* len_bits be multiple of 16K if repeat is set */
+ } else {
+ len_bytes = len_bits;
+ len_bits = len_bytes << 3;
+ }
+ p = REALLOC(st->buf, st->size + len_bytes + 1);
+ if(!p) RETURN(RC_FAIL);
+ st->buf = (uint8_t *)p;
+
+ ret = per_get_many_bits(pd, &st->buf[st->size], 0, len_bits);
+ if(ret < 0) RETURN(RC_WMORE);
+ st->size += len_bytes;
+ } while(repeat);
+ st->buf[st->size] = 0; /* nul-terminate */
+
+ return rval;
+}
+
+asn_enc_rval_t
+OCTET_STRING_encode_uper(asn_TYPE_descriptor_t *td,
+ asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
+
+ asn_OCTET_STRING_specifics_t *specs = td->specifics
+ ? (asn_OCTET_STRING_specifics_t *)td->specifics
+ : &asn_DEF_OCTET_STRING_specs;
+ asn_per_constraint_t *ct = constraints ? &constraints->size
+ : (td->per_constraints
+ ? &td->per_constraints->size
+ : &asn_DEF_OCTET_STRING_constraint);
+ const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;
+ int unit_bits = (specs->subvariant != 1) * 7 + 1;
+ asn_enc_rval_t er;
+ int ct_extensible = ct->flags & APC_EXTENSIBLE;
+ int inext = 0; /* Lies not within extension root */
+ int sizeinunits = st->size;
+ const uint8_t *buf;
+ int ret;
+
+ if(!st || !st->buf)
+ _ASN_ENCODE_FAILED;
+
+ if(unit_bits == 1) {
+ ASN_DEBUG("BIT STRING of %d bytes, %d bits unused",
+ sizeinunits, st->bits_unused);
+ sizeinunits = sizeinunits * 8 - (st->bits_unused & 0x07);
+ }
+
+ ASN_DEBUG("Encoding %s into %d units of %d bits"
+ " (%d..%d, effective %d)%s",
+ td->name, sizeinunits, unit_bits,
+ ct->lower_bound, ct->upper_bound,
+ ct->effective_bits, ct_extensible ? " EXT" : "");
+
+ /* Figure out wheter size lies within PER visible consrtaint */
+
+ if(ct->effective_bits >= 0) {
+ if(sizeinunits < ct->lower_bound
+ || sizeinunits > ct->upper_bound) {
+ if(ct_extensible) {
+ ct = &asn_DEF_OCTET_STRING_constraint;
+ inext = 1;
+ } else
+ _ASN_ENCODE_FAILED;
+ }
+ } else {
+ inext = 0;
+ }
+
+ if(ct_extensible) {
+ /* Declare whether length is [not] within extension root */
+ if(per_put_few_bits(po, inext, 1))
+ _ASN_ENCODE_FAILED;
+ }
+
+ /* X.691, #16.5: zero-length encoding */
+ /* X.691, #16.6: short fixed length encoding (up to 2 octets) */
+ /* X.691, #16.7: long fixed length encoding (up to 64K octets) */
+ if(ct->effective_bits >= 0) {
+ ASN_DEBUG("Encoding %d bytes (%ld), length in %d bits",
+ st->size, sizeinunits - ct->lower_bound,
+ ct->effective_bits);
+ ret = per_put_few_bits(po, sizeinunits - ct->lower_bound,
+ ct->effective_bits);
+ if(ret) _ASN_ENCODE_FAILED;
+ ret = per_put_many_bits(po, st->buf, sizeinunits * unit_bits);
+ if(ret) _ASN_ENCODE_FAILED;
+ _ASN_ENCODED_OK(er);
+ }
+
+ ASN_DEBUG("Encoding %d bytes", st->size);
+
+ if(sizeinunits == 0) {
+ if(uper_put_length(po, 0))
+ _ASN_ENCODE_FAILED;
+ _ASN_ENCODED_OK(er);
+ }
+
+ buf = st->buf;
+ while(sizeinunits) {
+ ssize_t maySave = uper_put_length(po, sizeinunits);
+ if(maySave < 0) _ASN_ENCODE_FAILED;
+
+ ASN_DEBUG("Encoding %d of %d", maySave, sizeinunits);
+
+ ret = per_put_many_bits(po, buf, maySave * unit_bits);
+ if(ret) _ASN_ENCODE_FAILED;
+
+ if(unit_bits == 1)
+ buf += maySave >> 3;
+ else
+ buf += maySave;
+ sizeinunits -= maySave;
+ assert(!(maySave & 0x07) || !sizeinunits);
+ }
+
+ _ASN_ENCODED_OK(er);
+}
+
+int
+OCTET_STRING_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ static const char *h2c = "0123456789ABCDEF";
+ const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr;
+ char scratch[16 * 3 + 4];
+ char *p = scratch;
+ uint8_t *buf;
+ uint8_t *end;
+ size_t i;
+
+ (void)td; /* Unused argument */
+
+ if(!st || !st->buf) return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
+
+ /*
+ * Dump the contents of the buffer in hexadecimal.
+ */
+ buf = st->buf;
+ end = buf + st->size;
+ for(i = 0; buf < end; buf++, i++) {
+ if(!(i % 16) && (i || st->size > 16)) {
+ if(cb(scratch, p - scratch, app_key) < 0)
+ return -1;
+ _i_INDENT(1);
+ p = scratch;
+ }
+ *p++ = h2c[(*buf >> 4) & 0x0F];
+ *p++ = h2c[*buf & 0x0F];
+ *p++ = 0x20;
+ }
+
+ if(p > scratch) {
+ p--; /* Remove the tail space */
+ if(cb(scratch, p - scratch, app_key) < 0)
+ return -1;
+ }
+
+ return 0;
+}
+
+int
+OCTET_STRING_print_utf8(asn_TYPE_descriptor_t *td, const void *sptr,
+ int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
+ const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr;
+
+ (void)td; /* Unused argument */
+ (void)ilevel; /* Unused argument */
+
+ if(st && st->buf) {
+ return (cb(st->buf, st->size, app_key) < 0) ? -1 : 0;
+ } else {
+ return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
+ }
+}
+
+void
+OCTET_STRING_free(asn_TYPE_descriptor_t *td, void *sptr, int contents_only) {
+ OCTET_STRING_t *st = (OCTET_STRING_t *)sptr;
+ asn_OCTET_STRING_specifics_t *specs = td->specifics
+ ? (asn_OCTET_STRING_specifics_t *)td->specifics
+ : &asn_DEF_OCTET_STRING_specs;
+ asn_struct_ctx_t *ctx = (asn_struct_ctx_t *)
+ ((char *)st + specs->ctx_offset);
+ struct _stack *stck;
+
+ if(!td || !st)
+ return;
+
+ ASN_DEBUG("Freeing %s as OCTET STRING", td->name);
+
+ if(st->buf) {
+ FREEMEM(st->buf);
+ }
+
+ /*
+ * Remove decode-time stack.
+ */
+ stck = (struct _stack *)ctx->ptr;
+ if(stck) {
+ while(stck->tail) {
+ struct _stack_el *sel = stck->tail;
+ stck->tail = sel->prev;
+ FREEMEM(sel);
+ }
+ FREEMEM(stck);
+ }
+
+ if(!contents_only) {
+ FREEMEM(st);
+ }
+}
+
+/*
+ * Conversion routines.
+ */
+int
+OCTET_STRING_fromBuf(OCTET_STRING_t *st, const char *str, int len) {
+ void *buf;
+
+ if(st == 0 || (str == 0 && len)) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ /*
+ * Clear the OCTET STRING.
+ */
+ if(str == NULL) {
+ FREEMEM(st->buf);
+ st->buf = 0;
+ st->size = 0;
+ return 0;
+ }
+
+ /* Determine the original string size, if not explicitly given */
+ if(len < 0)
+ len = strlen(str);
+
+ /* Allocate and fill the memory */
+ buf = MALLOC(len + 1);
+ if(buf == NULL)
+ return -1;
+
+ memcpy(buf, str, len);
+ ((uint8_t *)buf)[len] = '\0'; /* Couldn't use memcpy(len+1)! */
+ FREEMEM(st->buf);
+ st->buf = (uint8_t *)buf;
+ st->size = len;
+
+ return 0;
+}
+
+OCTET_STRING_t *
+OCTET_STRING_new_fromBuf(asn_TYPE_descriptor_t *td, const char *str, int len) {
+ asn_OCTET_STRING_specifics_t *specs = td->specifics
+ ? (asn_OCTET_STRING_specifics_t *)td->specifics
+ : &asn_DEF_OCTET_STRING_specs;
+ OCTET_STRING_t *st;
+
+ st = (OCTET_STRING_t *)CALLOC(1, specs->struct_size);
+ if(st && str && OCTET_STRING_fromBuf(st, str, len)) {
+ FREEMEM(st);
+ st = NULL;
+ }
+
+ return st;
+}
+
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1155-SMI"
+ * found in "RFC1155-SMI.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#include <asn_internal.h>
+
+#include "ObjectName.h"
+
+int
+ObjectName_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
+ asn_app_constraint_failed_f *ctfailcb, void *app_key) {
+ /* Replace with underlying type checker */
+ td->check_constraints = asn_DEF_OBJECT_IDENTIFIER.check_constraints;
+ return td->check_constraints(td, sptr, ctfailcb, app_key);
+}
+
+/*
+ * This type is implemented using OBJECT_IDENTIFIER,
+ * so here we adjust the DEF accordingly.
+ */
+static void
+ObjectName_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
+ td->free_struct = asn_DEF_OBJECT_IDENTIFIER.free_struct;
+ td->print_struct = asn_DEF_OBJECT_IDENTIFIER.print_struct;
+ td->ber_decoder = asn_DEF_OBJECT_IDENTIFIER.ber_decoder;
+ td->der_encoder = asn_DEF_OBJECT_IDENTIFIER.der_encoder;
+ td->xer_decoder = asn_DEF_OBJECT_IDENTIFIER.xer_decoder;
+ td->xer_encoder = asn_DEF_OBJECT_IDENTIFIER.xer_encoder;
+ td->uper_decoder = asn_DEF_OBJECT_IDENTIFIER.uper_decoder;
+ td->uper_encoder = asn_DEF_OBJECT_IDENTIFIER.uper_encoder;
+ if(!td->per_constraints)
+ td->per_constraints = asn_DEF_OBJECT_IDENTIFIER.per_constraints;
+ td->elements = asn_DEF_OBJECT_IDENTIFIER.elements;
+ td->elements_count = asn_DEF_OBJECT_IDENTIFIER.elements_count;
+ td->specifics = asn_DEF_OBJECT_IDENTIFIER.specifics;
+}
+
+void
+ObjectName_free(asn_TYPE_descriptor_t *td,
+ void *struct_ptr, int contents_only) {
+ ObjectName_1_inherit_TYPE_descriptor(td);
+ td->free_struct(td, struct_ptr, contents_only);
+}
+
+int
+ObjectName_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
+ int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
+ ObjectName_1_inherit_TYPE_descriptor(td);
+ return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
+}
+
+asn_dec_rval_t
+ObjectName_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ void **structure, const void *bufptr, size_t size, int tag_mode) {
+ ObjectName_1_inherit_TYPE_descriptor(td);
+ return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode);
+}
+
+asn_enc_rval_t
+ObjectName_encode_der(asn_TYPE_descriptor_t *td,
+ void *structure, int tag_mode, ber_tlv_tag_t tag,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ ObjectName_1_inherit_TYPE_descriptor(td);
+ return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
+}
+
+asn_dec_rval_t
+ObjectName_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ void **structure, const char *opt_mname, const void *bufptr, size_t size) {
+ ObjectName_1_inherit_TYPE_descriptor(td);
+ return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size);
+}
+
+asn_enc_rval_t
+ObjectName_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ ObjectName_1_inherit_TYPE_descriptor(td);
+ return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
+}
+
+static ber_tlv_tag_t asn_DEF_ObjectName_tags_1[] = {
+ (ASN_TAG_CLASS_UNIVERSAL | (6 << 2))
+};
+asn_TYPE_descriptor_t asn_DEF_ObjectName = {
+ "ObjectName",
+ "ObjectName",
+ ObjectName_free,
+ ObjectName_print,
+ ObjectName_constraint,
+ ObjectName_decode_ber,
+ ObjectName_encode_der,
+ ObjectName_decode_xer,
+ ObjectName_encode_xer,
+ 0, 0, /* No PER support, use "-gen-PER" to enable */
+ 0, /* Use generic outmost tag fetcher */
+ asn_DEF_ObjectName_tags_1,
+ sizeof(asn_DEF_ObjectName_tags_1)
+ /sizeof(asn_DEF_ObjectName_tags_1[0]), /* 1 */
+ asn_DEF_ObjectName_tags_1, /* Same as above */
+ sizeof(asn_DEF_ObjectName_tags_1)
+ /sizeof(asn_DEF_ObjectName_tags_1[0]), /* 1 */
+ 0, /* No PER visible constraints */
+ 0, 0, /* No members */
+ 0 /* No specifics */
+};
+
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1155-SMI"
+ * found in "RFC1155-SMI.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#include <asn_internal.h>
+
+#include "ObjectSyntax.h"
+
+static asn_TYPE_member_t asn_MBR_ObjectSyntax_1[] = {
+ { ATF_NOFLAGS, 0, offsetof(struct ObjectSyntax, choice.simple),
+ -1 /* Ambiguous tag (CHOICE?) */,
+ 0,
+ &asn_DEF_SimpleSyntax,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "simple"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct ObjectSyntax, choice.application_wide),
+ -1 /* Ambiguous tag (CHOICE?) */,
+ 0,
+ &asn_DEF_ApplicationSyntax,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "application-wide"
+ },
+};
+static asn_TYPE_tag2member_t asn_MAP_ObjectSyntax_tag2el_1[] = {
+ { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 0 }, /* number at 73 */
+ { (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 0, 0, 0 }, /* string at 76 */
+ { (ASN_TAG_CLASS_UNIVERSAL | (5 << 2)), 0, 0, 0 }, /* empty at 82 */
+ { (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)), 0, 0, 0 }, /* object at 79 */
+ { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 1, 0, 0 }, /* internet at 113 */
+ { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 1, 0, 0 }, /* counter at 91 */
+ { (ASN_TAG_CLASS_APPLICATION | (2 << 2)), 1, 0, 0 }, /* gauge at 94 */
+ { (ASN_TAG_CLASS_APPLICATION | (3 << 2)), 1, 0, 0 }, /* ticks at 97 */
+ { (ASN_TAG_CLASS_APPLICATION | (4 << 2)), 1, 0, 0 } /* arbitrary at 104 */
+};
+static asn_CHOICE_specifics_t asn_SPC_ObjectSyntax_specs_1 = {
+ sizeof(struct ObjectSyntax),
+ offsetof(struct ObjectSyntax, _asn_ctx),
+ offsetof(struct ObjectSyntax, present),
+ sizeof(((struct ObjectSyntax *)0)->present),
+ asn_MAP_ObjectSyntax_tag2el_1,
+ 9, /* Count of tags in the map */
+ 0,
+ -1 /* Extensions start */
+};
+asn_TYPE_descriptor_t asn_DEF_ObjectSyntax = {
+ "ObjectSyntax",
+ "ObjectSyntax",
+ CHOICE_free,
+ CHOICE_print,
+ CHOICE_constraint,
+ CHOICE_decode_ber,
+ CHOICE_encode_der,
+ CHOICE_decode_xer,
+ CHOICE_encode_xer,
+ 0, 0, /* No PER support, use "-gen-PER" to enable */
+ CHOICE_outmost_tag,
+ 0, /* No effective tags (pointer) */
+ 0, /* No effective tags (count) */
+ 0, /* No tags (pointer) */
+ 0, /* No tags (count) */
+ 0, /* No PER visible constraints */
+ asn_MBR_ObjectSyntax_1,
+ 2, /* Elements count */
+ &asn_SPC_ObjectSyntax_specs_1 /* Additional specs */
+};
+
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1155-SMI"
+ * found in "RFC1155-SMI.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#include <asn_internal.h>
+
+#include "Opaque.h"
+
+int
+Opaque_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
+ asn_app_constraint_failed_f *ctfailcb, void *app_key) {
+ /* Replace with underlying type checker */
+ td->check_constraints = asn_DEF_OCTET_STRING.check_constraints;
+ return td->check_constraints(td, sptr, ctfailcb, app_key);
+}
+
+/*
+ * This type is implemented using OCTET_STRING,
+ * so here we adjust the DEF accordingly.
+ */
+static void
+Opaque_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
+ td->free_struct = asn_DEF_OCTET_STRING.free_struct;
+ td->print_struct = asn_DEF_OCTET_STRING.print_struct;
+ td->ber_decoder = asn_DEF_OCTET_STRING.ber_decoder;
+ td->der_encoder = asn_DEF_OCTET_STRING.der_encoder;
+ td->xer_decoder = asn_DEF_OCTET_STRING.xer_decoder;
+ td->xer_encoder = asn_DEF_OCTET_STRING.xer_encoder;
+ td->uper_decoder = asn_DEF_OCTET_STRING.uper_decoder;
+ td->uper_encoder = asn_DEF_OCTET_STRING.uper_encoder;
+ if(!td->per_constraints)
+ td->per_constraints = asn_DEF_OCTET_STRING.per_constraints;
+ td->elements = asn_DEF_OCTET_STRING.elements;
+ td->elements_count = asn_DEF_OCTET_STRING.elements_count;
+ td->specifics = asn_DEF_OCTET_STRING.specifics;
+}
+
+void
+Opaque_free(asn_TYPE_descriptor_t *td,
+ void *struct_ptr, int contents_only) {
+ Opaque_1_inherit_TYPE_descriptor(td);
+ td->free_struct(td, struct_ptr, contents_only);
+}
+
+int
+Opaque_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
+ int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
+ Opaque_1_inherit_TYPE_descriptor(td);
+ return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
+}
+
+asn_dec_rval_t
+Opaque_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ void **structure, const void *bufptr, size_t size, int tag_mode) {
+ Opaque_1_inherit_TYPE_descriptor(td);
+ return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode);
+}
+
+asn_enc_rval_t
+Opaque_encode_der(asn_TYPE_descriptor_t *td,
+ void *structure, int tag_mode, ber_tlv_tag_t tag,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ Opaque_1_inherit_TYPE_descriptor(td);
+ return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
+}
+
+asn_dec_rval_t
+Opaque_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ void **structure, const char *opt_mname, const void *bufptr, size_t size) {
+ Opaque_1_inherit_TYPE_descriptor(td);
+ return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size);
+}
+
+asn_enc_rval_t
+Opaque_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ Opaque_1_inherit_TYPE_descriptor(td);
+ return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
+}
+
+static ber_tlv_tag_t asn_DEF_Opaque_tags_1[] = {
+ (ASN_TAG_CLASS_APPLICATION | (4 << 2)),
+ (ASN_TAG_CLASS_UNIVERSAL | (4 << 2))
+};
+asn_TYPE_descriptor_t asn_DEF_Opaque = {
+ "Opaque",
+ "Opaque",
+ Opaque_free,
+ Opaque_print,
+ Opaque_constraint,
+ Opaque_decode_ber,
+ Opaque_encode_der,
+ Opaque_decode_xer,
+ Opaque_encode_xer,
+ 0, 0, /* No PER support, use "-gen-PER" to enable */
+ 0, /* Use generic outmost tag fetcher */
+ asn_DEF_Opaque_tags_1,
+ sizeof(asn_DEF_Opaque_tags_1)
+ /sizeof(asn_DEF_Opaque_tags_1[0]) - 1, /* 1 */
+ asn_DEF_Opaque_tags_1, /* Same as above */
+ sizeof(asn_DEF_Opaque_tags_1)
+ /sizeof(asn_DEF_Opaque_tags_1[0]), /* 2 */
+ 0, /* No PER visible constraints */
+ 0, 0, /* No members */
+ 0 /* No specifics */
+};
+
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "SMUX"
+ * found in "SMUX.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#include <asn_internal.h>
+
+#include "OpenPDU.h"
+
+static asn_TYPE_member_t asn_MBR_OpenPDU_1[] = {
+ { ATF_NOFLAGS, 0, offsetof(struct OpenPDU, choice.simple),
+ (ASN_TAG_CLASS_APPLICATION | (0 << 2)),
+ 0,
+ &asn_DEF_SimpleOpen,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "simple"
+ },
+};
+static asn_TYPE_tag2member_t asn_MAP_OpenPDU_tag2el_1[] = {
+ { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 0, 0, 0 } /* simple at 52 */
+};
+static asn_CHOICE_specifics_t asn_SPC_OpenPDU_specs_1 = {
+ sizeof(struct OpenPDU),
+ offsetof(struct OpenPDU, _asn_ctx),
+ offsetof(struct OpenPDU, present),
+ sizeof(((struct OpenPDU *)0)->present),
+ asn_MAP_OpenPDU_tag2el_1,
+ 1, /* Count of tags in the map */
+ 0,
+ -1 /* Extensions start */
+};
+asn_TYPE_descriptor_t asn_DEF_OpenPDU = {
+ "OpenPDU",
+ "OpenPDU",
+ CHOICE_free,
+ CHOICE_print,
+ CHOICE_constraint,
+ CHOICE_decode_ber,
+ CHOICE_encode_der,
+ CHOICE_decode_xer,
+ CHOICE_encode_xer,
+ 0, 0, /* No PER support, use "-gen-PER" to enable */
+ CHOICE_outmost_tag,
+ 0, /* No effective tags (pointer) */
+ 0, /* No effective tags (count) */
+ 0, /* No tags (pointer) */
+ 0, /* No tags (count) */
+ 0, /* No PER visible constraints */
+ asn_MBR_OpenPDU_1,
+ 1, /* Elements count */
+ &asn_SPC_OpenPDU_specs_1 /* Additional specs */
+};
+
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1157-SNMP"
+ * found in "RFC1157-SNMP.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#include <asn_internal.h>
+
+#include "PDU.h"
+
+static asn_TYPE_member_t asn_MBR_PDU_1[] = {
+ { ATF_NOFLAGS, 0, offsetof(struct PDU, request_id),
+ (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
+ 0,
+ &asn_DEF_INTEGER,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "request-id"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct PDU, error_status),
+ (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
+ 0,
+ &asn_DEF_INTEGER,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "error-status"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct PDU, error_index),
+ (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
+ 0,
+ &asn_DEF_INTEGER,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "error-index"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct PDU, variable_bindings),
+ (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)),
+ 0,
+ &asn_DEF_VarBindList,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "variable-bindings"
+ },
+};
+static ber_tlv_tag_t asn_DEF_PDU_tags_1[] = {
+ (ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
+};
+static asn_TYPE_tag2member_t asn_MAP_PDU_tag2el_1[] = {
+ { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 2 }, /* request-id at 73 */
+ { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 1, -1, 1 }, /* error-status at 77 */
+ { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 2, -2, 0 }, /* error-index at 86 */
+ { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)), 3, 0, 0 } /* variable-bindings at 90 */
+};
+static asn_SEQUENCE_specifics_t asn_SPC_PDU_specs_1 = {
+ sizeof(struct PDU),
+ offsetof(struct PDU, _asn_ctx),
+ asn_MAP_PDU_tag2el_1,
+ 4, /* Count of tags in the map */
+ 0, 0, 0, /* Optional elements (not needed) */
+ -1, /* Start extensions */
+ -1 /* Stop extensions */
+};
+asn_TYPE_descriptor_t asn_DEF_PDU = {
+ "PDU",
+ "PDU",
+ SEQUENCE_free,
+ SEQUENCE_print,
+ SEQUENCE_constraint,
+ SEQUENCE_decode_ber,
+ SEQUENCE_encode_der,
+ SEQUENCE_decode_xer,
+ SEQUENCE_encode_xer,
+ 0, 0, /* No PER support, use "-gen-PER" to enable */
+ 0, /* Use generic outmost tag fetcher */
+ asn_DEF_PDU_tags_1,
+ sizeof(asn_DEF_PDU_tags_1)
+ /sizeof(asn_DEF_PDU_tags_1[0]), /* 1 */
+ asn_DEF_PDU_tags_1, /* Same as above */
+ sizeof(asn_DEF_PDU_tags_1)
+ /sizeof(asn_DEF_PDU_tags_1[0]), /* 1 */
+ 0, /* No PER visible constraints */
+ asn_MBR_PDU_1,
+ 4, /* Elements count */
+ &asn_SPC_PDU_specs_1 /* Additional specs */
+};
+
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1157-SNMP"
+ * found in "RFC1157-SNMP.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#include <asn_internal.h>
+
+#include "PDUs.h"
+
+static asn_TYPE_member_t asn_MBR_PDUs_1[] = {
+ { ATF_NOFLAGS, 0, offsetof(struct PDUs, choice.get_request),
+ (ASN_TAG_CLASS_CONTEXT | (0 << 2)),
+ 0,
+ &asn_DEF_GetRequest_PDU,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "get-request"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct PDUs, choice.get_next_request),
+ (ASN_TAG_CLASS_CONTEXT | (1 << 2)),
+ 0,
+ &asn_DEF_GetNextRequest_PDU,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "get-next-request"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct PDUs, choice.get_response),
+ (ASN_TAG_CLASS_CONTEXT | (2 << 2)),
+ 0,
+ &asn_DEF_GetResponse_PDU,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "get-response"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct PDUs, choice.set_request),
+ (ASN_TAG_CLASS_CONTEXT | (3 << 2)),
+ 0,
+ &asn_DEF_SetRequest_PDU,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "set-request"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct PDUs, choice.trap),
+ (ASN_TAG_CLASS_CONTEXT | (4 << 2)),
+ 0,
+ &asn_DEF_Trap_PDU,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "trap"
+ },
+};
+static asn_TYPE_tag2member_t asn_MAP_PDUs_tag2el_1[] = {
+ { (ASN_TAG_CLASS_CONTEXT | (0 << 2)), 0, 0, 0 }, /* get-request at 34 */
+ { (ASN_TAG_CLASS_CONTEXT | (1 << 2)), 1, 0, 0 }, /* get-next-request at 37 */
+ { (ASN_TAG_CLASS_CONTEXT | (2 << 2)), 2, 0, 0 }, /* get-response at 40 */
+ { (ASN_TAG_CLASS_CONTEXT | (3 << 2)), 3, 0, 0 }, /* set-request at 43 */
+ { (ASN_TAG_CLASS_CONTEXT | (4 << 2)), 4, 0, 0 } /* trap at 47 */
+};
+static asn_CHOICE_specifics_t asn_SPC_PDUs_specs_1 = {
+ sizeof(struct PDUs),
+ offsetof(struct PDUs, _asn_ctx),
+ offsetof(struct PDUs, present),
+ sizeof(((struct PDUs *)0)->present),
+ asn_MAP_PDUs_tag2el_1,
+ 5, /* Count of tags in the map */
+ 0,
+ -1 /* Extensions start */
+};
+asn_TYPE_descriptor_t asn_DEF_PDUs = {
+ "PDUs",
+ "PDUs",
+ CHOICE_free,
+ CHOICE_print,
+ CHOICE_constraint,
+ CHOICE_decode_ber,
+ CHOICE_encode_der,
+ CHOICE_decode_xer,
+ CHOICE_encode_xer,
+ 0, 0, /* No PER support, use "-gen-PER" to enable */
+ CHOICE_outmost_tag,
+ 0, /* No effective tags (pointer) */
+ 0, /* No effective tags (count) */
+ 0, /* No tags (pointer) */
+ 0, /* No tags (count) */
+ 0, /* No PER visible constraints */
+ asn_MBR_PDUs_1,
+ 5, /* Elements count */
+ &asn_SPC_PDUs_specs_1 /* Additional specs */
+};
+
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1213-MIB"
+ * found in "RFC1213-MIB.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#include <asn_internal.h>
+
+#include "PhysAddress.h"
+
+int
+PhysAddress_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
+ asn_app_constraint_failed_f *ctfailcb, void *app_key) {
+ /* Replace with underlying type checker */
+ td->check_constraints = asn_DEF_OCTET_STRING.check_constraints;
+ return td->check_constraints(td, sptr, ctfailcb, app_key);
+}
+
+/*
+ * This type is implemented using OCTET_STRING,
+ * so here we adjust the DEF accordingly.
+ */
+static void
+PhysAddress_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
+ td->free_struct = asn_DEF_OCTET_STRING.free_struct;
+ td->print_struct = asn_DEF_OCTET_STRING.print_struct;
+ td->ber_decoder = asn_DEF_OCTET_STRING.ber_decoder;
+ td->der_encoder = asn_DEF_OCTET_STRING.der_encoder;
+ td->xer_decoder = asn_DEF_OCTET_STRING.xer_decoder;
+ td->xer_encoder = asn_DEF_OCTET_STRING.xer_encoder;
+ td->uper_decoder = asn_DEF_OCTET_STRING.uper_decoder;
+ td->uper_encoder = asn_DEF_OCTET_STRING.uper_encoder;
+ if(!td->per_constraints)
+ td->per_constraints = asn_DEF_OCTET_STRING.per_constraints;
+ td->elements = asn_DEF_OCTET_STRING.elements;
+ td->elements_count = asn_DEF_OCTET_STRING.elements_count;
+ td->specifics = asn_DEF_OCTET_STRING.specifics;
+}
+
+void
+PhysAddress_free(asn_TYPE_descriptor_t *td,
+ void *struct_ptr, int contents_only) {
+ PhysAddress_1_inherit_TYPE_descriptor(td);
+ td->free_struct(td, struct_ptr, contents_only);
+}
+
+int
+PhysAddress_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
+ int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
+ PhysAddress_1_inherit_TYPE_descriptor(td);
+ return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
+}
+
+asn_dec_rval_t
+PhysAddress_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ void **structure, const void *bufptr, size_t size, int tag_mode) {
+ PhysAddress_1_inherit_TYPE_descriptor(td);
+ return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode);
+}
+
+asn_enc_rval_t
+PhysAddress_encode_der(asn_TYPE_descriptor_t *td,
+ void *structure, int tag_mode, ber_tlv_tag_t tag,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ PhysAddress_1_inherit_TYPE_descriptor(td);
+ return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
+}
+
+asn_dec_rval_t
+PhysAddress_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ void **structure, const char *opt_mname, const void *bufptr, size_t size) {
+ PhysAddress_1_inherit_TYPE_descriptor(td);
+ return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size);
+}
+
+asn_enc_rval_t
+PhysAddress_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ PhysAddress_1_inherit_TYPE_descriptor(td);
+ return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
+}
+
+static ber_tlv_tag_t asn_DEF_PhysAddress_tags_1[] = {
+ (ASN_TAG_CLASS_UNIVERSAL | (4 << 2))
+};
+asn_TYPE_descriptor_t asn_DEF_PhysAddress = {
+ "PhysAddress",
+ "PhysAddress",
+ PhysAddress_free,
+ PhysAddress_print,
+ PhysAddress_constraint,
+ PhysAddress_decode_ber,
+ PhysAddress_encode_der,
+ PhysAddress_decode_xer,
+ PhysAddress_encode_xer,
+ 0, 0, /* No PER support, use "-gen-PER" to enable */
+ 0, /* Use generic outmost tag fetcher */
+ asn_DEF_PhysAddress_tags_1,
+ sizeof(asn_DEF_PhysAddress_tags_1)
+ /sizeof(asn_DEF_PhysAddress_tags_1[0]), /* 1 */
+ asn_DEF_PhysAddress_tags_1, /* Same as above */
+ sizeof(asn_DEF_PhysAddress_tags_1)
+ /sizeof(asn_DEF_PhysAddress_tags_1[0]), /* 1 */
+ 0, /* No PER visible constraints */
+ 0, 0, /* No members */
+ 0 /* No specifics */
+};
+
--- /dev/null
+
+-- WinAgents MIB Extraction Wizard\r
+-- Extracted from rfc1155.txt 17.03.2005 16:16:50\r
+\r
+RFC1155-SMI DEFINITIONS ::= BEGIN\r
+\r
+--EXPORTS EVERYTHING\r
+-- internet, directory, mgmt,\r
+-- experimental, private, enterprises,\r
+-- OBJECT-TYPE, ObjectName, ObjectSyntax, SimpleSyntax,\r
+-- ApplicationSyntax, NetworkAddress, IpAddress,\r
+-- Counter, Gauge, TimeTicks, Opaque;\r
+\r
+ -- the path to the root\r
+\r
+ internet OBJECT IDENTIFIER ::= { iso org(3) dod(6) 1 }\r
+\r
+ directory OBJECT IDENTIFIER ::= { internet 1 }\r
+\r
+ mgmt OBJECT IDENTIFIER ::= { internet 2 }\r
+\r
+ experimental OBJECT IDENTIFIER ::= { internet 3 }\r
+\r
+ private OBJECT IDENTIFIER ::= { internet 4 }\r
+ enterprises OBJECT IDENTIFIER ::= { private 1 }\r
+\r
+\r
+ -- definition of object types\r
+\r
+-- MIB Extraction: All MACRO definitions are predefined by compiler\r
+-- commented by MIB Extraction: OBJECT-TYPE MACRO ::=\r
+-- commented by MIB Extraction: BEGIN\r
+-- commented by MIB Extraction: TYPE NOTATION ::= "SYNTAX" type (TYPE ObjectSyntax)\r
+-- commented by MIB Extraction: "ACCESS" Access\r
+-- commented by MIB Extraction: "STATUS" Status\r
+-- commented by MIB Extraction: VALUE NOTATION ::= value (VALUE ObjectName)\r
+-- commented by MIB Extraction: \r
+-- commented by MIB Extraction: Access ::= "read-only"\r
+-- commented by MIB Extraction: | "read-write"\r
+-- commented by MIB Extraction: | "write-only"\r
+-- commented by MIB Extraction: | "not-accessible"\r
+-- commented by MIB Extraction: Status ::= "mandatory"\r
+-- commented by MIB Extraction: | "optional"\r
+-- commented by MIB Extraction: | "obsolete"\r
+-- commented by MIB Extraction: END\r
+\r
+ -- names of objects in the MIB\r
+\r
+ ObjectName ::=\r
+ OBJECT IDENTIFIER\r
+\r
+\r
+ -- syntax of objects in the MIB\r
+\r
+ ObjectSyntax ::=\r
+ CHOICE {\r
+ simple\r
+ SimpleSyntax,\r
+\r
+ -- note that simple SEQUENCEs are not directly\r
+ -- mentioned here to keep things simple (i.e.,\r
+ -- prevent mis-use). However, application-wide\r
+ -- types which are IMPLICITly encoded simple\r
+ -- SEQUENCEs may appear in the following CHOICE\r
+\r
+ application-wide\r
+ ApplicationSyntax\r
+ }\r
+\r
+ SimpleSyntax ::=\r
+ CHOICE {\r
+ number\r
+ INTEGER,\r
+\r
+ string\r
+ OCTET STRING,\r
+\r
+ object\r
+ OBJECT IDENTIFIER,\r
+\r
+ empty\r
+ NULL\r
+ }\r
+\r
+ ApplicationSyntax ::=\r
+ CHOICE {\r
+ address\r
+ NetworkAddress,\r
+\r
+ counter\r
+ Counter,\r
+\r
+ gauge\r
+ Gauge,\r
+\r
+ ticks\r
+ TimeTicks,\r
+\r
+ arbitrary\r
+ Opaque\r
+\r
+ -- other application-wide types, as they are\r
+ -- defined, will be added here\r
+ }\r
+\r
+\r
+ -- application-wide types\r
+\r
+ NetworkAddress ::=\r
+ CHOICE {\r
+ internet\r
+ IpAddress\r
+ }\r
+\r
+ IpAddress ::=\r
+ [APPLICATION 0] -- in network-byte order\r
+ IMPLICIT OCTET STRING (SIZE (4))\r
+\r
+ Counter ::=\r
+ [APPLICATION 1]\r
+ IMPLICIT INTEGER (0..4294967295)\r
+\r
+ Gauge ::=\r
+ [APPLICATION 2]\r
+ IMPLICIT INTEGER (0..4294967295)\r
+\r
+ TimeTicks ::=\r
+ [APPLICATION 3]\r
+ IMPLICIT INTEGER (0..4294967295)\r
+\r
+ Opaque ::=\r
+ [APPLICATION 4] -- arbitrary ASN.1 value,\r
+ IMPLICIT OCTET STRING -- "double-wrapped"\r
+\r
+ END\r
--- /dev/null
+
+-- WinAgents MIB Extraction Wizard\r
+-- Extracted from rfc1157.txt 16.03.2005 20:20:14\r
+\r
+RFC1157-SNMP DEFINITIONS ::= BEGIN\r
+\r
+ IMPORTS\r
+ ObjectName, ObjectSyntax, NetworkAddress, IpAddress, TimeTicks\r
+ FROM RFC1155-SMI;\r
+\r
+\r
+ -- top-level message\r
+\r
+ Message ::=\r
+ SEQUENCE {\r
+ version -- version-1 for this RFC\r
+ INTEGER {\r
+ version-1(0)\r
+ },\r
+\r
+ community -- community name\r
+ OCTET STRING,\r
+\r
+ data -- e.g., PDUs if trivial\r
+ ANY -- authentication is being used\r
+ }\r
+\r
+\r
+ -- protocol data units\r
+\r
+ PDUs ::=\r
+ CHOICE {\r
+ get-request\r
+ GetRequest-PDU,\r
+\r
+ get-next-request\r
+ GetNextRequest-PDU,\r
+\r
+ get-response\r
+ GetResponse-PDU,\r
+\r
+ set-request\r
+ SetRequest-PDU,\r
+\r
+ trap\r
+ Trap-PDU\r
+ }\r
+\r
+\r
+\r
+\r
+ -- PDUs\r
+\r
+ GetRequest-PDU ::=\r
+ [0]\r
+ IMPLICIT PDU\r
+\r
+ GetNextRequest-PDU ::=\r
+ [1]\r
+ IMPLICIT PDU\r
+\r
+ GetResponse-PDU ::=\r
+ [2]\r
+ IMPLICIT PDU\r
+\r
+ SetRequest-PDU ::=\r
+ [3]\r
+ IMPLICIT PDU\r
+\r
+ PDU ::=\r
+ SEQUENCE {\r
+ request-id\r
+ INTEGER,\r
+\r
+ error-status -- sometimes ignored\r
+ INTEGER {\r
+ noError(0),\r
+ tooBig(1),\r
+ noSuchName(2),\r
+ badValue(3),\r
+ readOnly(4),\r
+ genErr(5)\r
+ },\r
+\r
+ error-index -- sometimes ignored\r
+ INTEGER,\r
+\r
+ variable-bindings -- values are sometimes ignored\r
+ VarBindList\r
+ }\r
+\r
+ Trap-PDU ::=\r
+ [4]\r
+ IMPLICIT SEQUENCE {\r
+ enterprise -- type of object generating\r
+ -- trap, see sysObjectID in [5]\r
+\r
+\r
+ OBJECT IDENTIFIER,\r
+\r
+ agent-addr -- address of object generating\r
+ NetworkAddress, -- trap\r
+\r
+ generic-trap -- generic trap type\r
+ INTEGER {\r
+ coldStart(0),\r
+ warmStart(1),\r
+ linkDown(2),\r
+ linkUp(3),\r
+ authenticationFailure(4),\r
+ egpNeighborLoss(5),\r
+ enterpriseSpecific(6)\r
+ },\r
+\r
+ specific-trap -- specific code, present even\r
+ INTEGER, -- if generic-trap is not\r
+ -- enterpriseSpecific\r
+\r
+ time-stamp -- time elapsed between the last\r
+ TimeTicks, -- (re)initialization of the network\r
+ -- entity and the generation of the trap\r
+\r
+ variable-bindings -- "interesting" information\r
+ VarBindList\r
+ }\r
+\r
+\r
+ -- variable bindings\r
+\r
+ VarBind ::=\r
+ SEQUENCE {\r
+ name\r
+ ObjectName,\r
+\r
+ value\r
+ ObjectSyntax\r
+ }\r
+\r
+ VarBindList ::=\r
+ SEQUENCE OF\r
+ VarBind\r
+\r
+ END
\ No newline at end of file
--- /dev/null
+
+-- WinAgents MIB Extraction Wizard\r
+-- Extracted from rfc1213.txt 16.03.2005 20:20:14\r
+\r
+RFC1213-MIB DEFINITIONS ::= BEGIN\r
+\r
+IMPORTS\r
+ mgmt, NetworkAddress, IpAddress, Counter, Gauge,\r
+ TimeTicks\r
+ FROM RFC1155-SMI\r
+ OBJECT-TYPE\r
+ FROM RFC-1212;\r
+\r
+-- This MIB module uses the extended OBJECT-TYPE macro as\r
+-- defined in [14];\r
+\r
+\r
+-- MIB-II (same prefix as MIB-I)\r
+\r
+mib-2 OBJECT IDENTIFIER ::= { mgmt 1 }\r
+\r
+-- textual conventions\r
+\r
+DisplayString ::=\r
+ OCTET STRING\r
+-- This data type is used to model textual information taken\r
+-- from the NVT ASCII character set. By convention, objects\r
+-- with this syntax are declared as having\r
+\r
+--\r
+-- SIZE (0..255)\r
+\r
+PhysAddress ::=\r
+ OCTET STRING\r
+-- This data type is used to model media addresses. For many\r
+-- types of media, this will be in a binary representation.\r
+-- For example, an ethernet address would be represented as\r
+-- a string of 6 octets.\r
+\r
+\r
+-- groups in MIB-II\r
+\r
+system OBJECT IDENTIFIER ::= { mib-2 1 }\r
+\r
+interfaces OBJECT IDENTIFIER ::= { mib-2 2 }\r
+\r
+at OBJECT IDENTIFIER ::= { mib-2 3 }\r
+\r
+ip OBJECT IDENTIFIER ::= { mib-2 4 }\r
+\r
+icmp OBJECT IDENTIFIER ::= { mib-2 5 }\r
+\r
+tcp OBJECT IDENTIFIER ::= { mib-2 6 }\r
+\r
+udp OBJECT IDENTIFIER ::= { mib-2 7 }\r
+\r
+egp OBJECT IDENTIFIER ::= { mib-2 8 }\r
+\r
+-- historical (some say hysterical)\r
+-- cmot OBJECT IDENTIFIER ::= { mib-2 9 }\r
+\r
+transmission OBJECT IDENTIFIER ::= { mib-2 10 }\r
+\r
+snmp OBJECT IDENTIFIER ::= { mib-2 11 }\r
+\r
+\r
+-- the System group\r
+\r
+-- Implementation of the System group is mandatory for all\r
+-- systems. If an agent is not configured to have a value\r
+-- for any of these variables, a string of length 0 is\r
+-- returned.\r
+\r
+\r
+IfEntry ::=\r
+ SEQUENCE {\r
+ ifIndex\r
+ INTEGER,\r
+\r
+ ifDescr\r
+ DisplayString,\r
+ ifType\r
+ INTEGER,\r
+ ifMtu\r
+ INTEGER,\r
+ ifSpeed\r
+ Gauge,\r
+ ifPhysAddress\r
+ PhysAddress,\r
+ ifAdminStatus\r
+ INTEGER,\r
+ ifOperStatus\r
+ INTEGER,\r
+ ifLastChange\r
+ TimeTicks,\r
+ ifInOctets\r
+ Counter,\r
+ ifInUcastPkts\r
+ Counter,\r
+ ifInNUcastPkts\r
+ Counter,\r
+ ifInDiscards\r
+ Counter,\r
+ ifInErrors\r
+ Counter,\r
+ ifInUnknownProtos\r
+ Counter,\r
+ ifOutOctets\r
+ Counter,\r
+ ifOutUcastPkts\r
+ Counter,\r
+ ifOutNUcastPkts\r
+ Counter,\r
+ ifOutDiscards\r
+ Counter,\r
+ ifOutErrors\r
+ Counter,\r
+ ifOutQLen\r
+ Gauge,\r
+ ifSpecific\r
+ OBJECT IDENTIFIER\r
+ }\r
+\r
+\r
+-- the Address Translation group\r
+\r
+-- Implementation of the Address Translation group is\r
+-- mandatory for all systems. Note however that this group\r
+-- is deprecated by MIB-II. That is, it is being included\r
+\r
+-- solely for compatibility with MIB-I nodes, and will most\r
+-- likely be excluded from MIB-III nodes. From MIB-II and\r
+-- onwards, each network protocol group contains its own\r
+-- address translation tables.\r
+\r
+-- The Address Translation group contains one table which is\r
+-- the union across all interfaces of the translation tables\r
+-- for converting a NetworkAddress (e.g., an IP address) into\r
+-- a subnetwork-specific address. For lack of a better term,\r
+-- this document refers to such a subnetwork-specific address\r
+-- as a `physical' address.\r
+\r
+-- Examples of such translation tables are: for broadcast\r
+-- media where ARP is in use, the translation table is\r
+-- equivalent to the ARP cache; or, on an X.25 network where\r
+-- non-algorithmic translation to X.121 addresses is\r
+-- required, the translation table contains the\r
+-- NetworkAddress to X.121 address equivalences.\r
+\r
+\r
+AtEntry ::=\r
+ SEQUENCE {\r
+ atIfIndex\r
+ INTEGER,\r
+\r
+ atPhysAddress\r
+ PhysAddress,\r
+ atNetAddress\r
+ NetworkAddress\r
+ }\r
+\r
+\r
+\r
+\r
+\r
+-- the IP address table\r
+\r
+-- The IP address table contains this entity's IP addressing\r
+-- information.\r
+\r
+\r
+IpAddrEntry ::=\r
+ SEQUENCE {\r
+ ipAdEntAddr\r
+ IpAddress,\r
+ ipAdEntIfIndex\r
+ INTEGER,\r
+ ipAdEntNetMask\r
+ IpAddress,\r
+ ipAdEntBcastAddr\r
+ INTEGER,\r
+ ipAdEntReasmMaxSize\r
+ INTEGER (0..65535)\r
+ }\r
+\r
+\r
+IpRouteEntry ::=\r
+ SEQUENCE {\r
+ ipRouteDest\r
+ IpAddress,\r
+ ipRouteIfIndex\r
+ INTEGER,\r
+ ipRouteMetric1\r
+ INTEGER,\r
+ ipRouteMetric2\r
+ INTEGER,\r
+ ipRouteMetric3\r
+ INTEGER,\r
+ ipRouteMetric4\r
+ INTEGER,\r
+ ipRouteNextHop\r
+ IpAddress,\r
+ ipRouteType\r
+ INTEGER,\r
+ ipRouteProto\r
+ INTEGER,\r
+ ipRouteAge\r
+ INTEGER,\r
+ ipRouteMask\r
+ IpAddress,\r
+ ipRouteMetric5\r
+ INTEGER,\r
+\r
+ ipRouteInfo\r
+ OBJECT IDENTIFIER\r
+ }\r
+\r
+\r
+IpNetToMediaEntry ::=\r
+ SEQUENCE {\r
+ ipNetToMediaIfIndex\r
+ INTEGER,\r
+ ipNetToMediaPhysAddress\r
+ PhysAddress,\r
+ ipNetToMediaNetAddress\r
+ IpAddress,\r
+ ipNetToMediaType\r
+ INTEGER\r
+ }\r
+\r
+\r
+\r
+TcpConnEntry ::=\r
+ SEQUENCE {\r
+ tcpConnState\r
+ INTEGER,\r
+ tcpConnLocalAddress\r
+ IpAddress,\r
+ tcpConnLocalPort\r
+ INTEGER (0..65535),\r
+ tcpConnRemAddress\r
+ IpAddress,\r
+ tcpConnRemPort\r
+ INTEGER (0..65535)\r
+ }\r
+\r
+\r
+UdpEntry ::=\r
+ SEQUENCE {\r
+ udpLocalAddress\r
+ IpAddress,\r
+ udpLocalPort\r
+ INTEGER (0..65535)\r
+ }\r
+\r
+\r
+\r
+-- the EGP Neighbor table\r
+\r
+-- The EGP neighbor table contains information about this\r
+-- entity's EGP neighbors.\r
+\r
+\r
+EgpNeighEntry ::=\r
+ SEQUENCE {\r
+ egpNeighState\r
+ INTEGER,\r
+ egpNeighAddr\r
+ IpAddress,\r
+ egpNeighAs\r
+ INTEGER,\r
+ egpNeighInMsgs\r
+ Counter,\r
+ egpNeighInErrs\r
+ Counter,\r
+ egpNeighOutMsgs\r
+ Counter,\r
+ egpNeighOutErrs\r
+ Counter,\r
+\r
+ egpNeighInErrMsgs\r
+ Counter,\r
+ egpNeighOutErrMsgs\r
+ Counter,\r
+ egpNeighStateUps\r
+ Counter,\r
+ egpNeighStateDowns\r
+ Counter,\r
+ egpNeighIntervalHello\r
+ INTEGER,\r
+ egpNeighIntervalPoll\r
+ INTEGER,\r
+ egpNeighMode\r
+ INTEGER,\r
+ egpNeighEventTrigger\r
+ INTEGER\r
+ }\r
+\r
+\r
+\r
+-- the Transmission group\r
+\r
+-- Based on the transmission media underlying each interface\r
+-- on a system, the corresponding portion of the Transmission\r
+-- group is mandatory for that system.\r
+\r
+-- When Internet-standard definitions for managing\r
+-- transmission media are defined, the transmission group is\r
+-- used to provide a prefix for the names of those objects.\r
+\r
+-- Typically, such definitions reside in the experimental\r
+-- portion of the MIB until they are "proven", then as a\r
+-- part of the Internet standardization process, the\r
+-- definitions are accordingly elevated and a new object\r
+-- identifier, under the transmission group is defined. By\r
+-- convention, the name assigned is:\r
+--\r
+-- type OBJECT IDENTIFIER ::= { transmission number }\r
+--\r
+-- where "type" is the symbolic value used for the media in\r
+-- the ifType column of the ifTable object, and "number" is\r
+-- the actual integer value corresponding to the symbol.\r
+\r
+\r
+-- the SNMP group\r
+\r
+-- Implementation of the SNMP group is mandatory for all\r
+-- systems which support an SNMP protocol entity. Some of\r
+-- the objects defined below will be zero-valued in those\r
+-- SNMP implementations that are optimized to support only\r
+-- those functions specific to either a management agent or\r
+-- a management station. In particular, it should be\r
+-- observed that the objects below refer to an SNMP entity,\r
+-- and there may be several SNMP entities residing on a\r
+-- managed node (e.g., if the node is hosting acting as\r
+-- a management station).\r
+\r
+\r
+END\r
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "SMUX"
+ * found in "SMUX.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#include <asn_internal.h>
+
+#include "RReqPDU.h"
+
+static int
+memb_priority_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr,
+ asn_app_constraint_failed_f *ctfailcb, void *app_key) {
+ long value;
+
+ if(!sptr) {
+ _ASN_CTFAIL(app_key, td, sptr,
+ "%s: value not given (%s:%d)",
+ td->name, __FILE__, __LINE__);
+ return -1;
+ }
+
+ value = *(const long *)sptr;
+
+ if((value >= -1 && value <= 2147483647)) {
+ /* Constraint check succeeded */
+ return 0;
+ } else {
+ _ASN_CTFAIL(app_key, td, sptr,
+ "%s: constraint failed (%s:%d)",
+ td->name, __FILE__, __LINE__);
+ return -1;
+ }
+}
+
+static asn_TYPE_member_t asn_MBR_RReqPDU_1[] = {
+ { ATF_NOFLAGS, 0, offsetof(struct RReqPDU, subtree),
+ (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)),
+ 0,
+ &asn_DEF_ObjectName,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "subtree"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct RReqPDU, priority),
+ (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
+ 0,
+ &asn_DEF_NativeInteger,
+ memb_priority_constraint_1,
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "priority"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct RReqPDU, operation),
+ (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
+ 0,
+ &asn_DEF_INTEGER,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "operation"
+ },
+};
+static ber_tlv_tag_t asn_DEF_RReqPDU_tags_1[] = {
+ (ASN_TAG_CLASS_APPLICATION | (2 << 2)),
+ (ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
+};
+static asn_TYPE_tag2member_t asn_MAP_RReqPDU_tag2el_1[] = {
+ { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 1, 0, 1 }, /* priority at 96 */
+ { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 2, -1, 0 }, /* operation at 101 */
+ { (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)), 0, 0, 0 } /* subtree at 93 */
+};
+static asn_SEQUENCE_specifics_t asn_SPC_RReqPDU_specs_1 = {
+ sizeof(struct RReqPDU),
+ offsetof(struct RReqPDU, _asn_ctx),
+ asn_MAP_RReqPDU_tag2el_1,
+ 3, /* Count of tags in the map */
+ 0, 0, 0, /* Optional elements (not needed) */
+ -1, /* Start extensions */
+ -1 /* Stop extensions */
+};
+asn_TYPE_descriptor_t asn_DEF_RReqPDU = {
+ "RReqPDU",
+ "RReqPDU",
+ SEQUENCE_free,
+ SEQUENCE_print,
+ SEQUENCE_constraint,
+ SEQUENCE_decode_ber,
+ SEQUENCE_encode_der,
+ SEQUENCE_decode_xer,
+ SEQUENCE_encode_xer,
+ 0, 0, /* No PER support, use "-gen-PER" to enable */
+ 0, /* Use generic outmost tag fetcher */
+ asn_DEF_RReqPDU_tags_1,
+ sizeof(asn_DEF_RReqPDU_tags_1)
+ /sizeof(asn_DEF_RReqPDU_tags_1[0]) - 1, /* 1 */
+ asn_DEF_RReqPDU_tags_1, /* Same as above */
+ sizeof(asn_DEF_RReqPDU_tags_1)
+ /sizeof(asn_DEF_RReqPDU_tags_1[0]), /* 2 */
+ 0, /* No PER visible constraints */
+ asn_MBR_RReqPDU_1,
+ 3, /* Elements count */
+ &asn_SPC_RReqPDU_specs_1 /* Additional specs */
+};
+
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "SMUX"
+ * found in "SMUX.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#include <asn_internal.h>
+
+#include "RRspPDU.h"
+
+int
+RRspPDU_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
+ asn_app_constraint_failed_f *ctfailcb, void *app_key) {
+ /* Replace with underlying type checker */
+ td->check_constraints = asn_DEF_INTEGER.check_constraints;
+ return td->check_constraints(td, sptr, ctfailcb, app_key);
+}
+
+/*
+ * This type is implemented using INTEGER,
+ * so here we adjust the DEF accordingly.
+ */
+static void
+RRspPDU_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
+ td->free_struct = asn_DEF_INTEGER.free_struct;
+ td->print_struct = asn_DEF_INTEGER.print_struct;
+ td->ber_decoder = asn_DEF_INTEGER.ber_decoder;
+ td->der_encoder = asn_DEF_INTEGER.der_encoder;
+ td->xer_decoder = asn_DEF_INTEGER.xer_decoder;
+ td->xer_encoder = asn_DEF_INTEGER.xer_encoder;
+ td->uper_decoder = asn_DEF_INTEGER.uper_decoder;
+ td->uper_encoder = asn_DEF_INTEGER.uper_encoder;
+ if(!td->per_constraints)
+ td->per_constraints = asn_DEF_INTEGER.per_constraints;
+ td->elements = asn_DEF_INTEGER.elements;
+ td->elements_count = asn_DEF_INTEGER.elements_count;
+ td->specifics = asn_DEF_INTEGER.specifics;
+}
+
+void
+RRspPDU_free(asn_TYPE_descriptor_t *td,
+ void *struct_ptr, int contents_only) {
+ RRspPDU_1_inherit_TYPE_descriptor(td);
+ td->free_struct(td, struct_ptr, contents_only);
+}
+
+int
+RRspPDU_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
+ int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
+ RRspPDU_1_inherit_TYPE_descriptor(td);
+ return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
+}
+
+asn_dec_rval_t
+RRspPDU_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ void **structure, const void *bufptr, size_t size, int tag_mode) {
+ RRspPDU_1_inherit_TYPE_descriptor(td);
+ return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode);
+}
+
+asn_enc_rval_t
+RRspPDU_encode_der(asn_TYPE_descriptor_t *td,
+ void *structure, int tag_mode, ber_tlv_tag_t tag,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ RRspPDU_1_inherit_TYPE_descriptor(td);
+ return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
+}
+
+asn_dec_rval_t
+RRspPDU_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ void **structure, const char *opt_mname, const void *bufptr, size_t size) {
+ RRspPDU_1_inherit_TYPE_descriptor(td);
+ return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size);
+}
+
+asn_enc_rval_t
+RRspPDU_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ RRspPDU_1_inherit_TYPE_descriptor(td);
+ return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
+}
+
+static ber_tlv_tag_t asn_DEF_RRspPDU_tags_1[] = {
+ (ASN_TAG_CLASS_APPLICATION | (3 << 2)),
+ (ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
+};
+asn_TYPE_descriptor_t asn_DEF_RRspPDU = {
+ "RRspPDU",
+ "RRspPDU",
+ RRspPDU_free,
+ RRspPDU_print,
+ RRspPDU_constraint,
+ RRspPDU_decode_ber,
+ RRspPDU_encode_der,
+ RRspPDU_decode_xer,
+ RRspPDU_encode_xer,
+ 0, 0, /* No PER support, use "-gen-PER" to enable */
+ 0, /* Use generic outmost tag fetcher */
+ asn_DEF_RRspPDU_tags_1,
+ sizeof(asn_DEF_RRspPDU_tags_1)
+ /sizeof(asn_DEF_RRspPDU_tags_1[0]) - 1, /* 1 */
+ asn_DEF_RRspPDU_tags_1, /* Same as above */
+ sizeof(asn_DEF_RRspPDU_tags_1)
+ /sizeof(asn_DEF_RRspPDU_tags_1[0]), /* 2 */
+ 0, /* No PER visible constraints */
+ 0, 0, /* Defined elsewhere */
+ 0 /* No specifics */
+};
+
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "SMUX"
+ * found in "SMUX.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#include <asn_internal.h>
+
+#include "SMUX-PDUs.h"
+
+static asn_TYPE_member_t asn_MBR_SMUX_PDUs_1[] = {
+ { ATF_NOFLAGS, 0, offsetof(struct SMUX_PDUs, choice.open),
+ -1 /* Ambiguous tag (CHOICE?) */,
+ 0,
+ &asn_DEF_OpenPDU,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "open"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct SMUX_PDUs, choice.close),
+ (ASN_TAG_CLASS_APPLICATION | (1 << 2)),
+ 0,
+ &asn_DEF_ClosePDU,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "close"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct SMUX_PDUs, choice.registerRequest),
+ (ASN_TAG_CLASS_APPLICATION | (2 << 2)),
+ 0,
+ &asn_DEF_RReqPDU,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "registerRequest"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct SMUX_PDUs, choice.registerResponse),
+ (ASN_TAG_CLASS_APPLICATION | (3 << 2)),
+ 0,
+ &asn_DEF_RRspPDU,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "registerResponse"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct SMUX_PDUs, choice.pdus),
+ -1 /* Ambiguous tag (CHOICE?) */,
+ 0,
+ &asn_DEF_PDUs,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "pdus"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct SMUX_PDUs, choice.commitOrRollback),
+ (ASN_TAG_CLASS_APPLICATION | (4 << 2)),
+ 0,
+ &asn_DEF_SOutPDU,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "commitOrRollback"
+ },
+};
+static asn_TYPE_tag2member_t asn_MAP_SMUX_PDUs_tag2el_1[] = {
+ { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 0, 0, 0 }, /* simple at 52 */
+ { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 1, 0, 0 }, /* close at 27 */
+ { (ASN_TAG_CLASS_APPLICATION | (2 << 2)), 2, 0, 0 }, /* registerRequest at 30 */
+ { (ASN_TAG_CLASS_APPLICATION | (3 << 2)), 3, 0, 0 }, /* registerResponse at 33 */
+ { (ASN_TAG_CLASS_APPLICATION | (4 << 2)), 5, 0, 0 }, /* commitOrRollback at 41 */
+ { (ASN_TAG_CLASS_CONTEXT | (0 << 2)), 4, 0, 0 }, /* get-request at 34 */
+ { (ASN_TAG_CLASS_CONTEXT | (1 << 2)), 4, 0, 0 }, /* get-next-request at 37 */
+ { (ASN_TAG_CLASS_CONTEXT | (2 << 2)), 4, 0, 0 }, /* get-response at 40 */
+ { (ASN_TAG_CLASS_CONTEXT | (3 << 2)), 4, 0, 0 }, /* set-request at 43 */
+ { (ASN_TAG_CLASS_CONTEXT | (4 << 2)), 4, 0, 0 } /* trap at 47 */
+};
+static asn_CHOICE_specifics_t asn_SPC_SMUX_PDUs_specs_1 = {
+ sizeof(struct SMUX_PDUs),
+ offsetof(struct SMUX_PDUs, _asn_ctx),
+ offsetof(struct SMUX_PDUs, present),
+ sizeof(((struct SMUX_PDUs *)0)->present),
+ asn_MAP_SMUX_PDUs_tag2el_1,
+ 10, /* Count of tags in the map */
+ 0,
+ -1 /* Extensions start */
+};
+asn_TYPE_descriptor_t asn_DEF_SMUX_PDUs = {
+ "SMUX-PDUs",
+ "SMUX-PDUs",
+ CHOICE_free,
+ CHOICE_print,
+ CHOICE_constraint,
+ CHOICE_decode_ber,
+ CHOICE_encode_der,
+ CHOICE_decode_xer,
+ CHOICE_encode_xer,
+ 0, 0, /* No PER support, use "-gen-PER" to enable */
+ CHOICE_outmost_tag,
+ 0, /* No effective tags (pointer) */
+ 0, /* No effective tags (count) */
+ 0, /* No tags (pointer) */
+ 0, /* No tags (count) */
+ 0, /* No PER visible constraints */
+ asn_MBR_SMUX_PDUs_1,
+ 6, /* Elements count */
+ &asn_SPC_SMUX_PDUs_specs_1 /* Additional specs */
+};
+
--- /dev/null
+
+-- WinAgents MIB Extraction Wizard\r
+-- Extracted from rfc1227.txt 16.03.2005 20:20:14\r
+\r
+SMUX DEFINITIONS ::= BEGIN\r
+\r
+IMPORTS\r
+ ObjectName\r
+ FROM RFC1155-SMI\r
+ DisplayString\r
+ FROM RFC1213-MIB\r
+\r
+ PDUs\r
+ FROM RFC1157-SNMP;\r
+\r
+\r
+-- tags for SMUX-specific PDUs are application-wide to\r
+-- avoid conflict with tags for current (and future)\r
+-- SNMP-generic PDUs\r
+\r
+SMUX-PDUs ::=\r
+ CHOICE {\r
+ open -- SMUX peer uses\r
+ OpenPDU, -- immediately after TCP open\r
+\r
+ close -- either uses immediately before TCP close\r
+ ClosePDU,\r
+\r
+ registerRequest -- SMUX peer uses\r
+ RReqPDU,\r
+\r
+ registerResponse -- SNMP agent uses\r
+ RRspPDU,\r
+\r
+ PDUs, -- note that roles are reversed:\r
+ -- SNMP agent does get/get-next/set\r
+ -- SMUX peer does get-response/trap\r
+\r
+ commitOrRollback -- SNMP agent uses\r
+ SOutPDU\r
+ }\r
+\r
+\r
+-- open PDU\r
+-- currently only simple authentication\r
+\r
+OpenPDU ::=\r
+ CHOICE {\r
+ simple\r
+\r
+ SimpleOpen\r
+ }\r
+\r
+SimpleOpen ::=\r
+ [APPLICATION 0] IMPLICIT\r
+ SEQUENCE {\r
+ version -- of SMUX protocol\r
+ INTEGER {\r
+ version-1(0)\r
+ },\r
+\r
+ identity -- of SMUX peer, authoritative\r
+ OBJECT IDENTIFIER,\r
+\r
+ description -- of SMUX peer, implementation-specific\r
+ DisplayString,\r
+\r
+ password -- zero length indicates no authentication\r
+ OCTET STRING\r
+ }\r
+\r
+\r
+-- close PDU\r
+\r
+ClosePDU ::=\r
+ [APPLICATION 1] IMPLICIT\r
+ INTEGER {\r
+ goingDown(0),\r
+ unsupportedVersion(1),\r
+ packetFormat(2),\r
+ protocolError(3),\r
+ internalError(4),\r
+ authenticationFailure(5)\r
+ }\r
+\r
+\r
+-- insert PDU\r
+\r
+RReqPDU ::=\r
+ [APPLICATION 2] IMPLICIT\r
+ SEQUENCE {\r
+ subtree\r
+ ObjectName,\r
+\r
+ priority -- the lower the better, "-1" means default\r
+ INTEGER (-1..2147483647),\r
+\r
+ operation\r
+\r
+ INTEGER {\r
+ delete(0), -- remove registration\r
+ readOnly(1), -- add registration, objects are RO\r
+ readWrite(2) -- .., objects are RW\r
+ }\r
+ }\r
+\r
+RRspPDU ::=\r
+ [APPLICATION 3] IMPLICIT\r
+ INTEGER {\r
+ failure(-1)\r
+\r
+ -- on success the non-negative priority is returned\r
+ }\r
+\r
+SOutPDU ::=\r
+ [APPLICATION 4] IMPLICIT\r
+ INTEGER {\r
+ commit(0),\r
+ rollback(1)\r
+ }\r
+\r
+END
\ No newline at end of file
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "SMUX"
+ * found in "SMUX.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#include <asn_internal.h>
+
+#include "SOutPDU.h"
+
+int
+SOutPDU_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
+ asn_app_constraint_failed_f *ctfailcb, void *app_key) {
+ /* Replace with underlying type checker */
+ td->check_constraints = asn_DEF_INTEGER.check_constraints;
+ return td->check_constraints(td, sptr, ctfailcb, app_key);
+}
+
+/*
+ * This type is implemented using INTEGER,
+ * so here we adjust the DEF accordingly.
+ */
+static void
+SOutPDU_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
+ td->free_struct = asn_DEF_INTEGER.free_struct;
+ td->print_struct = asn_DEF_INTEGER.print_struct;
+ td->ber_decoder = asn_DEF_INTEGER.ber_decoder;
+ td->der_encoder = asn_DEF_INTEGER.der_encoder;
+ td->xer_decoder = asn_DEF_INTEGER.xer_decoder;
+ td->xer_encoder = asn_DEF_INTEGER.xer_encoder;
+ td->uper_decoder = asn_DEF_INTEGER.uper_decoder;
+ td->uper_encoder = asn_DEF_INTEGER.uper_encoder;
+ if(!td->per_constraints)
+ td->per_constraints = asn_DEF_INTEGER.per_constraints;
+ td->elements = asn_DEF_INTEGER.elements;
+ td->elements_count = asn_DEF_INTEGER.elements_count;
+ td->specifics = asn_DEF_INTEGER.specifics;
+}
+
+void
+SOutPDU_free(asn_TYPE_descriptor_t *td,
+ void *struct_ptr, int contents_only) {
+ SOutPDU_1_inherit_TYPE_descriptor(td);
+ td->free_struct(td, struct_ptr, contents_only);
+}
+
+int
+SOutPDU_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
+ int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
+ SOutPDU_1_inherit_TYPE_descriptor(td);
+ return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
+}
+
+asn_dec_rval_t
+SOutPDU_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ void **structure, const void *bufptr, size_t size, int tag_mode) {
+ SOutPDU_1_inherit_TYPE_descriptor(td);
+ return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode);
+}
+
+asn_enc_rval_t
+SOutPDU_encode_der(asn_TYPE_descriptor_t *td,
+ void *structure, int tag_mode, ber_tlv_tag_t tag,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ SOutPDU_1_inherit_TYPE_descriptor(td);
+ return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
+}
+
+asn_dec_rval_t
+SOutPDU_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ void **structure, const char *opt_mname, const void *bufptr, size_t size) {
+ SOutPDU_1_inherit_TYPE_descriptor(td);
+ return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size);
+}
+
+asn_enc_rval_t
+SOutPDU_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ SOutPDU_1_inherit_TYPE_descriptor(td);
+ return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
+}
+
+static ber_tlv_tag_t asn_DEF_SOutPDU_tags_1[] = {
+ (ASN_TAG_CLASS_APPLICATION | (4 << 2)),
+ (ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
+};
+asn_TYPE_descriptor_t asn_DEF_SOutPDU = {
+ "SOutPDU",
+ "SOutPDU",
+ SOutPDU_free,
+ SOutPDU_print,
+ SOutPDU_constraint,
+ SOutPDU_decode_ber,
+ SOutPDU_encode_der,
+ SOutPDU_decode_xer,
+ SOutPDU_encode_xer,
+ 0, 0, /* No PER support, use "-gen-PER" to enable */
+ 0, /* Use generic outmost tag fetcher */
+ asn_DEF_SOutPDU_tags_1,
+ sizeof(asn_DEF_SOutPDU_tags_1)
+ /sizeof(asn_DEF_SOutPDU_tags_1[0]) - 1, /* 1 */
+ asn_DEF_SOutPDU_tags_1, /* Same as above */
+ sizeof(asn_DEF_SOutPDU_tags_1)
+ /sizeof(asn_DEF_SOutPDU_tags_1[0]), /* 2 */
+ 0, /* No PER visible constraints */
+ 0, 0, /* Defined elsewhere */
+ 0 /* No specifics */
+};
+
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1157-SNMP"
+ * found in "RFC1157-SNMP.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#include <asn_internal.h>
+
+#include "SetRequest-PDU.h"
+
+int
+SetRequest_PDU_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
+ asn_app_constraint_failed_f *ctfailcb, void *app_key) {
+ /* Replace with underlying type checker */
+ td->check_constraints = asn_DEF_PDU.check_constraints;
+ return td->check_constraints(td, sptr, ctfailcb, app_key);
+}
+
+/*
+ * This type is implemented using PDU,
+ * so here we adjust the DEF accordingly.
+ */
+static void
+SetRequest_PDU_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
+ td->free_struct = asn_DEF_PDU.free_struct;
+ td->print_struct = asn_DEF_PDU.print_struct;
+ td->ber_decoder = asn_DEF_PDU.ber_decoder;
+ td->der_encoder = asn_DEF_PDU.der_encoder;
+ td->xer_decoder = asn_DEF_PDU.xer_decoder;
+ td->xer_encoder = asn_DEF_PDU.xer_encoder;
+ td->uper_decoder = asn_DEF_PDU.uper_decoder;
+ td->uper_encoder = asn_DEF_PDU.uper_encoder;
+ if(!td->per_constraints)
+ td->per_constraints = asn_DEF_PDU.per_constraints;
+ td->elements = asn_DEF_PDU.elements;
+ td->elements_count = asn_DEF_PDU.elements_count;
+ td->specifics = asn_DEF_PDU.specifics;
+}
+
+void
+SetRequest_PDU_free(asn_TYPE_descriptor_t *td,
+ void *struct_ptr, int contents_only) {
+ SetRequest_PDU_1_inherit_TYPE_descriptor(td);
+ td->free_struct(td, struct_ptr, contents_only);
+}
+
+int
+SetRequest_PDU_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
+ int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
+ SetRequest_PDU_1_inherit_TYPE_descriptor(td);
+ return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
+}
+
+asn_dec_rval_t
+SetRequest_PDU_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ void **structure, const void *bufptr, size_t size, int tag_mode) {
+ SetRequest_PDU_1_inherit_TYPE_descriptor(td);
+ return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode);
+}
+
+asn_enc_rval_t
+SetRequest_PDU_encode_der(asn_TYPE_descriptor_t *td,
+ void *structure, int tag_mode, ber_tlv_tag_t tag,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ SetRequest_PDU_1_inherit_TYPE_descriptor(td);
+ return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
+}
+
+asn_dec_rval_t
+SetRequest_PDU_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ void **structure, const char *opt_mname, const void *bufptr, size_t size) {
+ SetRequest_PDU_1_inherit_TYPE_descriptor(td);
+ return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size);
+}
+
+asn_enc_rval_t
+SetRequest_PDU_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ SetRequest_PDU_1_inherit_TYPE_descriptor(td);
+ return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
+}
+
+static ber_tlv_tag_t asn_DEF_SetRequest_PDU_tags_1[] = {
+ (ASN_TAG_CLASS_CONTEXT | (3 << 2)),
+ (ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
+};
+asn_TYPE_descriptor_t asn_DEF_SetRequest_PDU = {
+ "SetRequest-PDU",
+ "SetRequest-PDU",
+ SetRequest_PDU_free,
+ SetRequest_PDU_print,
+ SetRequest_PDU_constraint,
+ SetRequest_PDU_decode_ber,
+ SetRequest_PDU_encode_der,
+ SetRequest_PDU_decode_xer,
+ SetRequest_PDU_encode_xer,
+ 0, 0, /* No PER support, use "-gen-PER" to enable */
+ 0, /* Use generic outmost tag fetcher */
+ asn_DEF_SetRequest_PDU_tags_1,
+ sizeof(asn_DEF_SetRequest_PDU_tags_1)
+ /sizeof(asn_DEF_SetRequest_PDU_tags_1[0]) - 1, /* 1 */
+ asn_DEF_SetRequest_PDU_tags_1, /* Same as above */
+ sizeof(asn_DEF_SetRequest_PDU_tags_1)
+ /sizeof(asn_DEF_SetRequest_PDU_tags_1[0]), /* 2 */
+ 0, /* No PER visible constraints */
+ 0, 0, /* Defined elsewhere */
+ 0 /* No specifics */
+};
+
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "SMUX"
+ * found in "SMUX.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#include <asn_internal.h>
+
+#include "SimpleOpen.h"
+
+static asn_TYPE_member_t asn_MBR_SimpleOpen_1[] = {
+ { ATF_NOFLAGS, 0, offsetof(struct SimpleOpen, version),
+ (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
+ 0,
+ &asn_DEF_INTEGER,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "version"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct SimpleOpen, identity),
+ (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)),
+ 0,
+ &asn_DEF_OBJECT_IDENTIFIER,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "identity"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct SimpleOpen, description),
+ (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)),
+ 0,
+ &asn_DEF_DisplayString,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "description"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct SimpleOpen, password),
+ (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)),
+ 0,
+ &asn_DEF_OCTET_STRING,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "password"
+ },
+};
+static ber_tlv_tag_t asn_DEF_SimpleOpen_tags_1[] = {
+ (ASN_TAG_CLASS_APPLICATION | (0 << 2)),
+ (ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
+};
+static asn_TYPE_tag2member_t asn_MAP_SimpleOpen_tag2el_1[] = {
+ { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 0 }, /* version at 59 */
+ { (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 2, 0, 1 }, /* description at 66 */
+ { (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 3, -1, 0 }, /* password at 69 */
+ { (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)), 1, 0, 0 } /* identity at 63 */
+};
+static asn_SEQUENCE_specifics_t asn_SPC_SimpleOpen_specs_1 = {
+ sizeof(struct SimpleOpen),
+ offsetof(struct SimpleOpen, _asn_ctx),
+ asn_MAP_SimpleOpen_tag2el_1,
+ 4, /* Count of tags in the map */
+ 0, 0, 0, /* Optional elements (not needed) */
+ -1, /* Start extensions */
+ -1 /* Stop extensions */
+};
+asn_TYPE_descriptor_t asn_DEF_SimpleOpen = {
+ "SimpleOpen",
+ "SimpleOpen",
+ SEQUENCE_free,
+ SEQUENCE_print,
+ SEQUENCE_constraint,
+ SEQUENCE_decode_ber,
+ SEQUENCE_encode_der,
+ SEQUENCE_decode_xer,
+ SEQUENCE_encode_xer,
+ 0, 0, /* No PER support, use "-gen-PER" to enable */
+ 0, /* Use generic outmost tag fetcher */
+ asn_DEF_SimpleOpen_tags_1,
+ sizeof(asn_DEF_SimpleOpen_tags_1)
+ /sizeof(asn_DEF_SimpleOpen_tags_1[0]) - 1, /* 1 */
+ asn_DEF_SimpleOpen_tags_1, /* Same as above */
+ sizeof(asn_DEF_SimpleOpen_tags_1)
+ /sizeof(asn_DEF_SimpleOpen_tags_1[0]), /* 2 */
+ 0, /* No PER visible constraints */
+ asn_MBR_SimpleOpen_1,
+ 4, /* Elements count */
+ &asn_SPC_SimpleOpen_specs_1 /* Additional specs */
+};
+
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1155-SMI"
+ * found in "RFC1155-SMI.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#include <asn_internal.h>
+
+#include "SimpleSyntax.h"
+
+static asn_TYPE_member_t asn_MBR_SimpleSyntax_1[] = {
+ { ATF_NOFLAGS, 0, offsetof(struct SimpleSyntax, choice.number),
+ (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
+ 0,
+ &asn_DEF_INTEGER,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "number"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct SimpleSyntax, choice.string),
+ (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)),
+ 0,
+ &asn_DEF_OCTET_STRING,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "string"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct SimpleSyntax, choice.object),
+ (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)),
+ 0,
+ &asn_DEF_OBJECT_IDENTIFIER,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "object"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct SimpleSyntax, choice.empty),
+ (ASN_TAG_CLASS_UNIVERSAL | (5 << 2)),
+ 0,
+ &asn_DEF_NULL,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "empty"
+ },
+};
+static asn_TYPE_tag2member_t asn_MAP_SimpleSyntax_tag2el_1[] = {
+ { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 0 }, /* number at 73 */
+ { (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 1, 0, 0 }, /* string at 76 */
+ { (ASN_TAG_CLASS_UNIVERSAL | (5 << 2)), 3, 0, 0 }, /* empty at 82 */
+ { (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)), 2, 0, 0 } /* object at 79 */
+};
+static asn_CHOICE_specifics_t asn_SPC_SimpleSyntax_specs_1 = {
+ sizeof(struct SimpleSyntax),
+ offsetof(struct SimpleSyntax, _asn_ctx),
+ offsetof(struct SimpleSyntax, present),
+ sizeof(((struct SimpleSyntax *)0)->present),
+ asn_MAP_SimpleSyntax_tag2el_1,
+ 4, /* Count of tags in the map */
+ 0,
+ -1 /* Extensions start */
+};
+asn_TYPE_descriptor_t asn_DEF_SimpleSyntax = {
+ "SimpleSyntax",
+ "SimpleSyntax",
+ CHOICE_free,
+ CHOICE_print,
+ CHOICE_constraint,
+ CHOICE_decode_ber,
+ CHOICE_encode_der,
+ CHOICE_decode_xer,
+ CHOICE_encode_xer,
+ 0, 0, /* No PER support, use "-gen-PER" to enable */
+ CHOICE_outmost_tag,
+ 0, /* No effective tags (pointer) */
+ 0, /* No effective tags (count) */
+ 0, /* No tags (pointer) */
+ 0, /* No tags (count) */
+ 0, /* No PER visible constraints */
+ asn_MBR_SimpleSyntax_1,
+ 4, /* Elements count */
+ &asn_SPC_SimpleSyntax_specs_1 /* Additional specs */
+};
+
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1213-MIB"
+ * found in "RFC1213-MIB.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#include <asn_internal.h>
+
+#include "TcpConnEntry.h"
+
+static int
+memb_tcpConnLocalPort_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr,
+ asn_app_constraint_failed_f *ctfailcb, void *app_key) {
+ long value;
+
+ if(!sptr) {
+ _ASN_CTFAIL(app_key, td, sptr,
+ "%s: value not given (%s:%d)",
+ td->name, __FILE__, __LINE__);
+ return -1;
+ }
+
+ value = *(const long *)sptr;
+
+ if((value >= 0 && value <= 65535)) {
+ /* Constraint check succeeded */
+ return 0;
+ } else {
+ _ASN_CTFAIL(app_key, td, sptr,
+ "%s: constraint failed (%s:%d)",
+ td->name, __FILE__, __LINE__);
+ return -1;
+ }
+}
+
+static int
+memb_tcpConnRemPort_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr,
+ asn_app_constraint_failed_f *ctfailcb, void *app_key) {
+ long value;
+
+ if(!sptr) {
+ _ASN_CTFAIL(app_key, td, sptr,
+ "%s: value not given (%s:%d)",
+ td->name, __FILE__, __LINE__);
+ return -1;
+ }
+
+ value = *(const long *)sptr;
+
+ if((value >= 0 && value <= 65535)) {
+ /* Constraint check succeeded */
+ return 0;
+ } else {
+ _ASN_CTFAIL(app_key, td, sptr,
+ "%s: constraint failed (%s:%d)",
+ td->name, __FILE__, __LINE__);
+ return -1;
+ }
+}
+
+static asn_TYPE_member_t asn_MBR_TcpConnEntry_1[] = {
+ { ATF_NOFLAGS, 0, offsetof(struct TcpConnEntry, tcpConnState),
+ (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
+ 0,
+ &asn_DEF_INTEGER,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "tcpConnState"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct TcpConnEntry, tcpConnLocalAddress),
+ (ASN_TAG_CLASS_APPLICATION | (0 << 2)),
+ 0,
+ &asn_DEF_IpAddress,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "tcpConnLocalAddress"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct TcpConnEntry, tcpConnLocalPort),
+ (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
+ 0,
+ &asn_DEF_NativeInteger,
+ memb_tcpConnLocalPort_constraint_1,
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "tcpConnLocalPort"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct TcpConnEntry, tcpConnRemAddress),
+ (ASN_TAG_CLASS_APPLICATION | (0 << 2)),
+ 0,
+ &asn_DEF_IpAddress,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "tcpConnRemAddress"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct TcpConnEntry, tcpConnRemPort),
+ (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
+ 0,
+ &asn_DEF_NativeInteger,
+ memb_tcpConnRemPort_constraint_1,
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "tcpConnRemPort"
+ },
+};
+static ber_tlv_tag_t asn_DEF_TcpConnEntry_tags_1[] = {
+ (ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
+};
+static asn_TYPE_tag2member_t asn_MAP_TcpConnEntry_tag2el_1[] = {
+ { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 2 }, /* tcpConnState at 236 */
+ { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 2, -1, 1 }, /* tcpConnLocalPort at 240 */
+ { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 4, -2, 0 }, /* tcpConnRemPort at 244 */
+ { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 1, 0, 1 }, /* tcpConnLocalAddress at 238 */
+ { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 3, -1, 0 } /* tcpConnRemAddress at 242 */
+};
+static asn_SEQUENCE_specifics_t asn_SPC_TcpConnEntry_specs_1 = {
+ sizeof(struct TcpConnEntry),
+ offsetof(struct TcpConnEntry, _asn_ctx),
+ asn_MAP_TcpConnEntry_tag2el_1,
+ 5, /* Count of tags in the map */
+ 0, 0, 0, /* Optional elements (not needed) */
+ -1, /* Start extensions */
+ -1 /* Stop extensions */
+};
+asn_TYPE_descriptor_t asn_DEF_TcpConnEntry = {
+ "TcpConnEntry",
+ "TcpConnEntry",
+ SEQUENCE_free,
+ SEQUENCE_print,
+ SEQUENCE_constraint,
+ SEQUENCE_decode_ber,
+ SEQUENCE_encode_der,
+ SEQUENCE_decode_xer,
+ SEQUENCE_encode_xer,
+ 0, 0, /* No PER support, use "-gen-PER" to enable */
+ 0, /* Use generic outmost tag fetcher */
+ asn_DEF_TcpConnEntry_tags_1,
+ sizeof(asn_DEF_TcpConnEntry_tags_1)
+ /sizeof(asn_DEF_TcpConnEntry_tags_1[0]), /* 1 */
+ asn_DEF_TcpConnEntry_tags_1, /* Same as above */
+ sizeof(asn_DEF_TcpConnEntry_tags_1)
+ /sizeof(asn_DEF_TcpConnEntry_tags_1[0]), /* 1 */
+ 0, /* No PER visible constraints */
+ asn_MBR_TcpConnEntry_1,
+ 5, /* Elements count */
+ &asn_SPC_TcpConnEntry_specs_1 /* Additional specs */
+};
+
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1155-SMI"
+ * found in "RFC1155-SMI.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#include <asn_internal.h>
+
+#include "TimeTicks.h"
+
+int
+TimeTicks_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
+ asn_app_constraint_failed_f *ctfailcb, void *app_key) {
+ const INTEGER_t *st = (const INTEGER_t *)sptr;
+ long value;
+
+ if(!sptr) {
+ _ASN_CTFAIL(app_key, td, sptr,
+ "%s: value not given (%s:%d)",
+ td->name, __FILE__, __LINE__);
+ return -1;
+ }
+
+ if(asn_INTEGER2long(st, &value)) {
+ _ASN_CTFAIL(app_key, td, sptr,
+ "%s: value too large (%s:%d)",
+ td->name, __FILE__, __LINE__);
+ return -1;
+ }
+
+ if((value >= 0 && value <= 4294967295)) {
+ /* Constraint check succeeded */
+ return 0;
+ } else {
+ _ASN_CTFAIL(app_key, td, sptr,
+ "%s: constraint failed (%s:%d)",
+ td->name, __FILE__, __LINE__);
+ return -1;
+ }
+}
+
+/*
+ * This type is implemented using INTEGER,
+ * so here we adjust the DEF accordingly.
+ */
+static void
+TimeTicks_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
+ td->free_struct = asn_DEF_INTEGER.free_struct;
+ td->print_struct = asn_DEF_INTEGER.print_struct;
+ td->ber_decoder = asn_DEF_INTEGER.ber_decoder;
+ td->der_encoder = asn_DEF_INTEGER.der_encoder;
+ td->xer_decoder = asn_DEF_INTEGER.xer_decoder;
+ td->xer_encoder = asn_DEF_INTEGER.xer_encoder;
+ td->uper_decoder = asn_DEF_INTEGER.uper_decoder;
+ td->uper_encoder = asn_DEF_INTEGER.uper_encoder;
+ if(!td->per_constraints)
+ td->per_constraints = asn_DEF_INTEGER.per_constraints;
+ td->elements = asn_DEF_INTEGER.elements;
+ td->elements_count = asn_DEF_INTEGER.elements_count;
+ td->specifics = asn_DEF_INTEGER.specifics;
+}
+
+void
+TimeTicks_free(asn_TYPE_descriptor_t *td,
+ void *struct_ptr, int contents_only) {
+ TimeTicks_1_inherit_TYPE_descriptor(td);
+ td->free_struct(td, struct_ptr, contents_only);
+}
+
+int
+TimeTicks_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
+ int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
+ TimeTicks_1_inherit_TYPE_descriptor(td);
+ return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
+}
+
+asn_dec_rval_t
+TimeTicks_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ void **structure, const void *bufptr, size_t size, int tag_mode) {
+ TimeTicks_1_inherit_TYPE_descriptor(td);
+ return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode);
+}
+
+asn_enc_rval_t
+TimeTicks_encode_der(asn_TYPE_descriptor_t *td,
+ void *structure, int tag_mode, ber_tlv_tag_t tag,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ TimeTicks_1_inherit_TYPE_descriptor(td);
+ return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
+}
+
+asn_dec_rval_t
+TimeTicks_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ void **structure, const char *opt_mname, const void *bufptr, size_t size) {
+ TimeTicks_1_inherit_TYPE_descriptor(td);
+ return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size);
+}
+
+asn_enc_rval_t
+TimeTicks_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ TimeTicks_1_inherit_TYPE_descriptor(td);
+ return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
+}
+
+static ber_tlv_tag_t asn_DEF_TimeTicks_tags_1[] = {
+ (ASN_TAG_CLASS_APPLICATION | (3 << 2)),
+ (ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
+};
+asn_TYPE_descriptor_t asn_DEF_TimeTicks = {
+ "TimeTicks",
+ "TimeTicks",
+ TimeTicks_free,
+ TimeTicks_print,
+ TimeTicks_constraint,
+ TimeTicks_decode_ber,
+ TimeTicks_encode_der,
+ TimeTicks_decode_xer,
+ TimeTicks_encode_xer,
+ 0, 0, /* No PER support, use "-gen-PER" to enable */
+ 0, /* Use generic outmost tag fetcher */
+ asn_DEF_TimeTicks_tags_1,
+ sizeof(asn_DEF_TimeTicks_tags_1)
+ /sizeof(asn_DEF_TimeTicks_tags_1[0]) - 1, /* 1 */
+ asn_DEF_TimeTicks_tags_1, /* Same as above */
+ sizeof(asn_DEF_TimeTicks_tags_1)
+ /sizeof(asn_DEF_TimeTicks_tags_1[0]), /* 2 */
+ 0, /* No PER visible constraints */
+ 0, 0, /* No members */
+ 0 /* No specifics */
+};
+
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1157-SNMP"
+ * found in "RFC1157-SNMP.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#include <asn_internal.h>
+
+#include "Trap-PDU.h"
+
+static asn_TYPE_member_t asn_MBR_Trap_PDU_1[] = {
+ { ATF_NOFLAGS, 0, offsetof(struct Trap_PDU, enterprise),
+ (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)),
+ 0,
+ &asn_DEF_OBJECT_IDENTIFIER,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "enterprise"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct Trap_PDU, agent_addr),
+ -1 /* Ambiguous tag (CHOICE?) */,
+ 0,
+ &asn_DEF_NetworkAddress,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "agent-addr"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct Trap_PDU, generic_trap),
+ (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
+ 0,
+ &asn_DEF_INTEGER,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "generic-trap"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct Trap_PDU, specific_trap),
+ (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
+ 0,
+ &asn_DEF_INTEGER,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "specific-trap"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct Trap_PDU, time_stamp),
+ (ASN_TAG_CLASS_APPLICATION | (3 << 2)),
+ 0,
+ &asn_DEF_TimeTicks,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "time-stamp"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct Trap_PDU, variable_bindings),
+ (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)),
+ 0,
+ &asn_DEF_VarBindList,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "variable-bindings"
+ },
+};
+static ber_tlv_tag_t asn_DEF_Trap_PDU_tags_1[] = {
+ (ASN_TAG_CLASS_CONTEXT | (4 << 2)),
+ (ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
+};
+static asn_TYPE_tag2member_t asn_MAP_Trap_PDU_tag2el_1[] = {
+ { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 2, 0, 1 }, /* generic-trap at 106 */
+ { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 3, -1, 0 }, /* specific-trap at 116 */
+ { (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)), 0, 0, 0 }, /* enterprise at 99 */
+ { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)), 5, 0, 0 }, /* variable-bindings at 125 */
+ { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 1, 0, 0 }, /* internet at 113 */
+ { (ASN_TAG_CLASS_APPLICATION | (3 << 2)), 4, 0, 0 } /* time-stamp at 120 */
+};
+static asn_SEQUENCE_specifics_t asn_SPC_Trap_PDU_specs_1 = {
+ sizeof(struct Trap_PDU),
+ offsetof(struct Trap_PDU, _asn_ctx),
+ asn_MAP_Trap_PDU_tag2el_1,
+ 6, /* Count of tags in the map */
+ 0, 0, 0, /* Optional elements (not needed) */
+ -1, /* Start extensions */
+ -1 /* Stop extensions */
+};
+asn_TYPE_descriptor_t asn_DEF_Trap_PDU = {
+ "Trap-PDU",
+ "Trap-PDU",
+ SEQUENCE_free,
+ SEQUENCE_print,
+ SEQUENCE_constraint,
+ SEQUENCE_decode_ber,
+ SEQUENCE_encode_der,
+ SEQUENCE_decode_xer,
+ SEQUENCE_encode_xer,
+ 0, 0, /* No PER support, use "-gen-PER" to enable */
+ 0, /* Use generic outmost tag fetcher */
+ asn_DEF_Trap_PDU_tags_1,
+ sizeof(asn_DEF_Trap_PDU_tags_1)
+ /sizeof(asn_DEF_Trap_PDU_tags_1[0]) - 1, /* 1 */
+ asn_DEF_Trap_PDU_tags_1, /* Same as above */
+ sizeof(asn_DEF_Trap_PDU_tags_1)
+ /sizeof(asn_DEF_Trap_PDU_tags_1[0]), /* 2 */
+ 0, /* No PER visible constraints */
+ asn_MBR_Trap_PDU_1,
+ 6, /* Elements count */
+ &asn_SPC_Trap_PDU_specs_1 /* Additional specs */
+};
+
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1213-MIB"
+ * found in "RFC1213-MIB.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#include <asn_internal.h>
+
+#include "UdpEntry.h"
+
+static int
+memb_udpLocalPort_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr,
+ asn_app_constraint_failed_f *ctfailcb, void *app_key) {
+ long value;
+
+ if(!sptr) {
+ _ASN_CTFAIL(app_key, td, sptr,
+ "%s: value not given (%s:%d)",
+ td->name, __FILE__, __LINE__);
+ return -1;
+ }
+
+ value = *(const long *)sptr;
+
+ if((value >= 0 && value <= 65535)) {
+ /* Constraint check succeeded */
+ return 0;
+ } else {
+ _ASN_CTFAIL(app_key, td, sptr,
+ "%s: constraint failed (%s:%d)",
+ td->name, __FILE__, __LINE__);
+ return -1;
+ }
+}
+
+static asn_TYPE_member_t asn_MBR_UdpEntry_1[] = {
+ { ATF_NOFLAGS, 0, offsetof(struct UdpEntry, udpLocalAddress),
+ (ASN_TAG_CLASS_APPLICATION | (0 << 2)),
+ 0,
+ &asn_DEF_IpAddress,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "udpLocalAddress"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct UdpEntry, udpLocalPort),
+ (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
+ 0,
+ &asn_DEF_NativeInteger,
+ memb_udpLocalPort_constraint_1,
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "udpLocalPort"
+ },
+};
+static ber_tlv_tag_t asn_DEF_UdpEntry_tags_1[] = {
+ (ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
+};
+static asn_TYPE_tag2member_t asn_MAP_UdpEntry_tag2el_1[] = {
+ { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 1, 0, 0 }, /* udpLocalPort at 253 */
+ { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 0, 0, 0 } /* udpLocalAddress at 251 */
+};
+static asn_SEQUENCE_specifics_t asn_SPC_UdpEntry_specs_1 = {
+ sizeof(struct UdpEntry),
+ offsetof(struct UdpEntry, _asn_ctx),
+ asn_MAP_UdpEntry_tag2el_1,
+ 2, /* Count of tags in the map */
+ 0, 0, 0, /* Optional elements (not needed) */
+ -1, /* Start extensions */
+ -1 /* Stop extensions */
+};
+asn_TYPE_descriptor_t asn_DEF_UdpEntry = {
+ "UdpEntry",
+ "UdpEntry",
+ SEQUENCE_free,
+ SEQUENCE_print,
+ SEQUENCE_constraint,
+ SEQUENCE_decode_ber,
+ SEQUENCE_encode_der,
+ SEQUENCE_decode_xer,
+ SEQUENCE_encode_xer,
+ 0, 0, /* No PER support, use "-gen-PER" to enable */
+ 0, /* Use generic outmost tag fetcher */
+ asn_DEF_UdpEntry_tags_1,
+ sizeof(asn_DEF_UdpEntry_tags_1)
+ /sizeof(asn_DEF_UdpEntry_tags_1[0]), /* 1 */
+ asn_DEF_UdpEntry_tags_1, /* Same as above */
+ sizeof(asn_DEF_UdpEntry_tags_1)
+ /sizeof(asn_DEF_UdpEntry_tags_1[0]), /* 1 */
+ 0, /* No PER visible constraints */
+ asn_MBR_UdpEntry_1,
+ 2, /* Elements count */
+ &asn_SPC_UdpEntry_specs_1 /* Additional specs */
+};
+
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1157-SNMP"
+ * found in "RFC1157-SNMP.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#include <asn_internal.h>
+
+#include "VarBind.h"
+
+static asn_TYPE_member_t asn_MBR_VarBind_1[] = {
+ { ATF_NOFLAGS, 0, offsetof(struct VarBind, name),
+ (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)),
+ 0,
+ &asn_DEF_ObjectName,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "name"
+ },
+ { ATF_NOFLAGS, 0, offsetof(struct VarBind, value),
+ -1 /* Ambiguous tag (CHOICE?) */,
+ 0,
+ &asn_DEF_ObjectSyntax,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ "value"
+ },
+};
+static ber_tlv_tag_t asn_DEF_VarBind_tags_1[] = {
+ (ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
+};
+static asn_TYPE_tag2member_t asn_MAP_VarBind_tag2el_1[] = {
+ { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 1, 0, 0 }, /* number at 73 */
+ { (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 1, 0, 0 }, /* string at 76 */
+ { (ASN_TAG_CLASS_UNIVERSAL | (5 << 2)), 1, 0, 0 }, /* empty at 82 */
+ { (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)), 0, 0, 1 }, /* name at 133 */
+ { (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)), 1, -1, 0 }, /* object at 79 */
+ { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 1, 0, 0 }, /* internet at 113 */
+ { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 1, 0, 0 }, /* counter at 91 */
+ { (ASN_TAG_CLASS_APPLICATION | (2 << 2)), 1, 0, 0 }, /* gauge at 94 */
+ { (ASN_TAG_CLASS_APPLICATION | (3 << 2)), 1, 0, 0 }, /* ticks at 97 */
+ { (ASN_TAG_CLASS_APPLICATION | (4 << 2)), 1, 0, 0 } /* arbitrary at 104 */
+};
+static asn_SEQUENCE_specifics_t asn_SPC_VarBind_specs_1 = {
+ sizeof(struct VarBind),
+ offsetof(struct VarBind, _asn_ctx),
+ asn_MAP_VarBind_tag2el_1,
+ 10, /* Count of tags in the map */
+ 0, 0, 0, /* Optional elements (not needed) */
+ -1, /* Start extensions */
+ -1 /* Stop extensions */
+};
+asn_TYPE_descriptor_t asn_DEF_VarBind = {
+ "VarBind",
+ "VarBind",
+ SEQUENCE_free,
+ SEQUENCE_print,
+ SEQUENCE_constraint,
+ SEQUENCE_decode_ber,
+ SEQUENCE_encode_der,
+ SEQUENCE_decode_xer,
+ SEQUENCE_encode_xer,
+ 0, 0, /* No PER support, use "-gen-PER" to enable */
+ 0, /* Use generic outmost tag fetcher */
+ asn_DEF_VarBind_tags_1,
+ sizeof(asn_DEF_VarBind_tags_1)
+ /sizeof(asn_DEF_VarBind_tags_1[0]), /* 1 */
+ asn_DEF_VarBind_tags_1, /* Same as above */
+ sizeof(asn_DEF_VarBind_tags_1)
+ /sizeof(asn_DEF_VarBind_tags_1[0]), /* 1 */
+ 0, /* No PER visible constraints */
+ asn_MBR_VarBind_1,
+ 2, /* Elements count */
+ &asn_SPC_VarBind_specs_1 /* Additional specs */
+};
+
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1157-SNMP"
+ * found in "RFC1157-SNMP.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#include <asn_internal.h>
+
+#include "VarBindList.h"
+
+static asn_TYPE_member_t asn_MBR_VarBindList_1[] = {
+ { ATF_POINTER, 0, 0,
+ (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)),
+ 0,
+ &asn_DEF_VarBind,
+ 0, /* Defer constraints checking to the member type */
+ 0, /* PER is not compiled, use -gen-PER */
+ 0,
+ ""
+ },
+};
+static ber_tlv_tag_t asn_DEF_VarBindList_tags_1[] = {
+ (ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
+};
+static asn_SET_OF_specifics_t asn_SPC_VarBindList_specs_1 = {
+ sizeof(struct VarBindList),
+ offsetof(struct VarBindList, _asn_ctx),
+ 0, /* XER encoding is XMLDelimitedItemList */
+};
+asn_TYPE_descriptor_t asn_DEF_VarBindList = {
+ "VarBindList",
+ "VarBindList",
+ SEQUENCE_OF_free,
+ SEQUENCE_OF_print,
+ SEQUENCE_OF_constraint,
+ SEQUENCE_OF_decode_ber,
+ SEQUENCE_OF_encode_der,
+ SEQUENCE_OF_decode_xer,
+ SEQUENCE_OF_encode_xer,
+ 0, 0, /* No PER support, use "-gen-PER" to enable */
+ 0, /* Use generic outmost tag fetcher */
+ asn_DEF_VarBindList_tags_1,
+ sizeof(asn_DEF_VarBindList_tags_1)
+ /sizeof(asn_DEF_VarBindList_tags_1[0]), /* 1 */
+ asn_DEF_VarBindList_tags_1, /* Same as above */
+ sizeof(asn_DEF_VarBindList_tags_1)
+ /sizeof(asn_DEF_VarBindList_tags_1[0]), /* 1 */
+ 0, /* No PER visible constraints */
+ asn_MBR_VarBindList_1,
+ 1, /* Single element */
+ &asn_SPC_VarBindList_specs_1 /* Additional specs */
+};
+
--- /dev/null
+/*-
+ * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#include <asn_internal.h>
+#include <asn_SEQUENCE_OF.h>
+
+typedef A_SEQUENCE_OF(void) asn_sequence;
+
+void
+asn_sequence_del(void *asn_sequence_of_x, int number, int _do_free) {
+ asn_sequence *as = (asn_sequence *)asn_sequence_of_x;
+
+ if(as) {
+ void *ptr;
+ int n;
+
+ if(number < 0 || number >= as->count)
+ return; /* Nothing to delete */
+
+ if(_do_free && as->free) {
+ ptr = as->array[number];
+ } else {
+ ptr = 0;
+ }
+
+ /*
+ * Shift all elements to the left to hide the gap.
+ */
+ --as->count;
+ for(n = number; n < as->count; n++)
+ as->array[n] = as->array[n+1];
+
+ /*
+ * Invoke the third-party function only when the state
+ * of the parent structure is consistent.
+ */
+ if(ptr) as->free(ptr);
+ }
+}
+
--- /dev/null
+/*-
+ * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#include <asn_internal.h>
+#include <asn_SET_OF.h>
+#include <errno.h>
+
+/*
+ * Add another element into the set.
+ */
+int
+asn_set_add(void *asn_set_of_x, void *ptr) {
+ asn_anonymous_set_ *as = _A_SET_FROM_VOID(asn_set_of_x);
+
+ if(as == 0 || ptr == 0) {
+ errno = EINVAL; /* Invalid arguments */
+ return -1;
+ }
+
+ /*
+ * Make sure there's enough space to insert an element.
+ */
+ if(as->count == as->size) {
+ int _newsize = as->size ? (as->size << 1) : 4;
+ void *_new_arr;
+ _new_arr = REALLOC(as->array, _newsize * sizeof(as->array[0]));
+ if(_new_arr) {
+ as->array = (void **)_new_arr;
+ as->size = _newsize;
+ } else {
+ /* ENOMEM */
+ return -1;
+ }
+ }
+
+ as->array[as->count++] = ptr;
+
+ return 0;
+}
+
+void
+asn_set_del(void *asn_set_of_x, int number, int _do_free) {
+ asn_anonymous_set_ *as = _A_SET_FROM_VOID(asn_set_of_x);
+
+ if(as) {
+ void *ptr;
+ if(number < 0 || number >= as->count)
+ return;
+
+ if(_do_free && as->free) {
+ ptr = as->array[number];
+ } else {
+ ptr = 0;
+ }
+
+ as->array[number] = as->array[--as->count];
+
+ /*
+ * Invoke the third-party function only when the state
+ * of the parent structure is consistent.
+ */
+ if(ptr) as->free(ptr);
+ }
+}
+
+/*
+ * Free the contents of the set, do not free the set itself.
+ */
+void
+asn_set_empty(void *asn_set_of_x) {
+ asn_anonymous_set_ *as = _A_SET_FROM_VOID(asn_set_of_x);
+
+ if(as) {
+ if(as->array) {
+ if(as->free) {
+ while(as->count--)
+ as->free(as->array[as->count]);
+ }
+ FREEMEM(as->array);
+ as->array = 0;
+ }
+ as->count = 0;
+ as->size = 0;
+ }
+
+}
+
--- /dev/null
+/*-
+ * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#include <asn_internal.h>
+#include <asn_codecs_prim.h>
+#include <errno.h>
+
+/*
+ * Decode an always-primitive type.
+ */
+asn_dec_rval_t
+ber_decode_primitive(asn_codec_ctx_t *opt_codec_ctx,
+ asn_TYPE_descriptor_t *td,
+ void **sptr, const void *buf_ptr, size_t size, int tag_mode) {
+ ASN__PRIMITIVE_TYPE_t *st = (ASN__PRIMITIVE_TYPE_t *)*sptr;
+ asn_dec_rval_t rval;
+ ber_tlv_len_t length;
+
+ /*
+ * If the structure is not there, allocate it.
+ */
+ if(st == NULL) {
+ st = (ASN__PRIMITIVE_TYPE_t *)CALLOC(1, sizeof(*st));
+ if(st == NULL) _ASN_DECODE_FAILED;
+ *sptr = (void *)st;
+ }
+
+ ASN_DEBUG("Decoding %s as plain primitive (tm=%d)",
+ td->name, tag_mode);
+
+ /*
+ * Check tags and extract value length.
+ */
+ rval = ber_check_tags(opt_codec_ctx, td, 0, buf_ptr, size,
+ tag_mode, 0, &length, 0);
+ if(rval.code != RC_OK)
+ return rval;
+
+ ASN_DEBUG("%s length is %d bytes", td->name, (int)length);
+
+ /*
+ * Make sure we have this length.
+ */
+ buf_ptr = ((const char *)buf_ptr) + rval.consumed;
+ size -= rval.consumed;
+ if(length > (ber_tlv_len_t)size) {
+ rval.code = RC_WMORE;
+ rval.consumed = 0;
+ return rval;
+ }
+
+ st->size = (int)length;
+ /* The following better be optimized away. */
+ if(sizeof(st->size) != sizeof(length)
+ && (ber_tlv_len_t)st->size != length) {
+ st->size = 0;
+ _ASN_DECODE_FAILED;
+ }
+
+ st->buf = (uint8_t *)MALLOC(length + 1);
+ if(!st->buf) {
+ st->size = 0;
+ _ASN_DECODE_FAILED;
+ }
+
+ memcpy(st->buf, buf_ptr, length);
+ st->buf[length] = '\0'; /* Just in case */
+
+ rval.code = RC_OK;
+ rval.consumed += length;
+
+ ASN_DEBUG("Took %ld/%ld bytes to encode %s",
+ (long)rval.consumed,
+ (long)length, td->name);
+
+ return rval;
+}
+
+/*
+ * Encode an always-primitive type using DER.
+ */
+asn_enc_rval_t
+der_encode_primitive(asn_TYPE_descriptor_t *td, void *sptr,
+ int tag_mode, ber_tlv_tag_t tag,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ asn_enc_rval_t erval;
+ ASN__PRIMITIVE_TYPE_t *st = (ASN__PRIMITIVE_TYPE_t *)sptr;
+
+ ASN_DEBUG("%s %s as a primitive type (tm=%d)",
+ cb?"Encoding":"Estimating", td->name, tag_mode);
+
+ erval.encoded = der_write_tags(td, st->size, tag_mode, 0, tag,
+ cb, app_key);
+ ASN_DEBUG("%s wrote tags %d", td->name, (int)erval.encoded);
+ if(erval.encoded == -1) {
+ erval.failed_type = td;
+ erval.structure_ptr = sptr;
+ return erval;
+ }
+
+ if(cb && st->buf) {
+ if(cb(st->buf, st->size, app_key) < 0) {
+ erval.encoded = -1;
+ erval.failed_type = td;
+ erval.structure_ptr = sptr;
+ return erval;
+ }
+ } else {
+ assert(st->buf || st->size == 0);
+ }
+
+ erval.encoded += st->size;
+ _ASN_ENCODED_OK(erval);
+}
+
+void
+ASN__PRIMITIVE_TYPE_free(asn_TYPE_descriptor_t *td, void *sptr,
+ int contents_only) {
+ ASN__PRIMITIVE_TYPE_t *st = (ASN__PRIMITIVE_TYPE_t *)sptr;
+
+ if(!td || !sptr)
+ return;
+
+ ASN_DEBUG("Freeing %s as a primitive type", td->name);
+
+ if(st->buf)
+ FREEMEM(st->buf);
+
+ if(!contents_only)
+ FREEMEM(st);
+}
+
+
+/*
+ * Local internal type passed around as an argument.
+ */
+struct xdp_arg_s {
+ asn_TYPE_descriptor_t *type_descriptor;
+ void *struct_key;
+ xer_primitive_body_decoder_f *prim_body_decoder;
+ int decoded_something;
+ int want_more;
+};
+
+
+static int
+xer_decode__unexpected_tag(void *key, const void *chunk_buf, size_t chunk_size) {
+ struct xdp_arg_s *arg = (struct xdp_arg_s *)key;
+ enum xer_pbd_rval bret;
+
+ if(arg->decoded_something) {
+ if(xer_is_whitespace(chunk_buf, chunk_size))
+ return 0; /* Skip it. */
+ /*
+ * Decoding was done once already. Prohibit doing it again.
+ */
+ return -1;
+ }
+
+ bret = arg->prim_body_decoder(arg->type_descriptor,
+ arg->struct_key, chunk_buf, chunk_size);
+ switch(bret) {
+ case XPBD_SYSTEM_FAILURE:
+ case XPBD_DECODER_LIMIT:
+ case XPBD_BROKEN_ENCODING:
+ break;
+ case XPBD_BODY_CONSUMED:
+ /* Tag decoded successfully */
+ arg->decoded_something = 1;
+ /* Fall through */
+ case XPBD_NOT_BODY_IGNORE: /* Safe to proceed further */
+ return 0;
+ }
+
+ return -1;
+}
+
+static ssize_t
+xer_decode__body(void *key, const void *chunk_buf, size_t chunk_size, int have_more) {
+ struct xdp_arg_s *arg = (struct xdp_arg_s *)key;
+ enum xer_pbd_rval bret;
+
+ if(arg->decoded_something) {
+ if(xer_is_whitespace(chunk_buf, chunk_size))
+ return chunk_size;
+ /*
+ * Decoding was done once already. Prohibit doing it again.
+ */
+ return -1;
+ }
+
+ if(!have_more) {
+ /*
+ * If we've received something like "1", we can't really
+ * tell whether it is really `1` or `123`, until we know
+ * that there is no more data coming.
+ * The have_more argument will be set to 1 once something
+ * like this is available to the caller of this callback:
+ * "1<tag_start..."
+ */
+ arg->want_more = 1;
+ return -1;
+ }
+
+ bret = arg->prim_body_decoder(arg->type_descriptor,
+ arg->struct_key, chunk_buf, chunk_size);
+ switch(bret) {
+ case XPBD_SYSTEM_FAILURE:
+ case XPBD_DECODER_LIMIT:
+ case XPBD_BROKEN_ENCODING:
+ break;
+ case XPBD_BODY_CONSUMED:
+ /* Tag decoded successfully */
+ arg->decoded_something = 1;
+ /* Fall through */
+ case XPBD_NOT_BODY_IGNORE: /* Safe to proceed further */
+ return chunk_size;
+ }
+
+ return -1;
+}
+
+
+asn_dec_rval_t
+xer_decode_primitive(asn_codec_ctx_t *opt_codec_ctx,
+ asn_TYPE_descriptor_t *td,
+ void **sptr,
+ size_t struct_size,
+ const char *opt_mname,
+ const void *buf_ptr, size_t size,
+ xer_primitive_body_decoder_f *prim_body_decoder
+) {
+ const char *xml_tag = opt_mname ? opt_mname : td->xml_tag;
+ asn_struct_ctx_t s_ctx;
+ struct xdp_arg_s s_arg;
+ asn_dec_rval_t rc;
+
+ /*
+ * Create the structure if does not exist.
+ */
+ if(!*sptr) {
+ *sptr = CALLOC(1, struct_size);
+ if(!*sptr) _ASN_DECODE_FAILED;
+ }
+
+ memset(&s_ctx, 0, sizeof(s_ctx));
+ s_arg.type_descriptor = td;
+ s_arg.struct_key = *sptr;
+ s_arg.prim_body_decoder = prim_body_decoder;
+ s_arg.decoded_something = 0;
+ s_arg.want_more = 0;
+
+ rc = xer_decode_general(opt_codec_ctx, &s_ctx, &s_arg,
+ xml_tag, buf_ptr, size,
+ xer_decode__unexpected_tag, xer_decode__body);
+ switch(rc.code) {
+ case RC_OK:
+ if(!s_arg.decoded_something) {
+ char ch;
+ ASN_DEBUG("Primitive body is not recognized, "
+ "supplying empty one");
+ /*
+ * Decoding opportunity has come and gone.
+ * Where's the result?
+ * Try to feed with empty body, see if it eats it.
+ */
+ if(prim_body_decoder(s_arg.type_descriptor,
+ s_arg.struct_key, &ch, 0)
+ != XPBD_BODY_CONSUMED) {
+ /*
+ * This decoder does not like empty stuff.
+ */
+ _ASN_DECODE_FAILED;
+ }
+ }
+ break;
+ case RC_WMORE:
+ /*
+ * Redo the whole thing later.
+ * We don't have a context to save intermediate parsing state.
+ */
+ rc.consumed = 0;
+ break;
+ case RC_FAIL:
+ rc.consumed = 0;
+ if(s_arg.want_more)
+ rc.code = RC_WMORE;
+ else
+ _ASN_DECODE_FAILED;
+ break;
+ }
+ return rc;
+}
+
--- /dev/null
+/*-
+ * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#include <asn_internal.h>
+
+#undef ADVANCE
+#define ADVANCE(num_bytes) do { \
+ size_t num = num_bytes; \
+ ptr = ((const char *)ptr) + num; \
+ size -= num; \
+ consumed_myself += num; \
+ } while(0)
+#undef RETURN
+#define RETURN(_code) do { \
+ asn_dec_rval_t rval; \
+ rval.code = _code; \
+ if(opt_ctx) opt_ctx->step = step; /* Save context */ \
+ if(_code == RC_OK || opt_ctx) \
+ rval.consumed = consumed_myself; \
+ else \
+ rval.consumed = 0; /* Context-free */ \
+ return rval; \
+ } while(0)
+
+/*
+ * The BER decoder of any type.
+ */
+asn_dec_rval_t
+ber_decode(asn_codec_ctx_t *opt_codec_ctx,
+ asn_TYPE_descriptor_t *type_descriptor,
+ void **struct_ptr, const void *ptr, size_t size) {
+ asn_codec_ctx_t s_codec_ctx;
+
+ /*
+ * Stack checker requires that the codec context
+ * must be allocated on the stack.
+ */
+ if(opt_codec_ctx) {
+ if(opt_codec_ctx->max_stack_size) {
+ s_codec_ctx = *opt_codec_ctx;
+ opt_codec_ctx = &s_codec_ctx;
+ }
+ } else {
+ /* If context is not given, be security-conscious anyway */
+ memset(&s_codec_ctx, 0, sizeof(s_codec_ctx));
+ s_codec_ctx.max_stack_size = _ASN_DEFAULT_STACK_MAX;
+ opt_codec_ctx = &s_codec_ctx;
+ }
+
+ /*
+ * Invoke type-specific decoder.
+ */
+ return type_descriptor->ber_decoder(opt_codec_ctx, type_descriptor,
+ struct_ptr, /* Pointer to the destination structure */
+ ptr, size, /* Buffer and its size */
+ 0 /* Default tag mode is 0 */
+ );
+}
+
+/*
+ * Check the set of <TL<TL<TL...>>> tags matches the definition.
+ */
+asn_dec_rval_t
+ber_check_tags(asn_codec_ctx_t *opt_codec_ctx,
+ asn_TYPE_descriptor_t *td, asn_struct_ctx_t *opt_ctx,
+ const void *ptr, size_t size, int tag_mode, int last_tag_form,
+ ber_tlv_len_t *last_length, int *opt_tlv_form) {
+ ssize_t consumed_myself = 0;
+ ssize_t tag_len;
+ ssize_t len_len;
+ ber_tlv_tag_t tlv_tag;
+ ber_tlv_len_t tlv_len;
+ ber_tlv_len_t limit_len = -1;
+ int expect_00_terminators = 0;
+ int tlv_constr = -1; /* If CHOICE, opt_tlv_form is not given */
+ int step = opt_ctx ? opt_ctx->step : 0; /* Where we left previously */
+ int tagno;
+
+ /*
+ * Make sure we didn't exceed the maximum stack size.
+ */
+ if(_ASN_STACK_OVERFLOW_CHECK(opt_codec_ctx))
+ RETURN(RC_FAIL);
+
+ /*
+ * So what does all this implicit skip stuff mean?
+ * Imagine two types,
+ * A ::= [5] IMPLICIT T
+ * B ::= [2] EXPLICIT T
+ * Where T is defined as
+ * T ::= [4] IMPLICIT SEQUENCE { ... }
+ *
+ * Let's say, we are starting to decode type A, given the
+ * following TLV stream: <5> <0>. What does this mean?
+ * It means that the type A contains type T which is,
+ * in turn, empty.
+ * Remember though, that we are still in A. We cannot
+ * just pass control to the type T decoder. Why? Because
+ * the type T decoder expects <4> <0>, not <5> <0>.
+ * So, we must make sure we are going to receive <5> while
+ * still in A, then pass control to the T decoder, indicating
+ * that the tag <4> was implicitly skipped. The decoder of T
+ * hence will be prepared to treat <4> as valid tag, and decode
+ * it appropriately.
+ */
+
+ tagno = step /* Continuing where left previously */
+ + (tag_mode==1?-1:0)
+ ;
+ ASN_DEBUG("ber_check_tags(%s, size=%ld, tm=%d, step=%d, tagno=%d)",
+ td->name, (long)size, tag_mode, step, tagno);
+ /* assert(td->tags_count >= 1) May not be the case for CHOICE or ANY */
+
+ if(tag_mode == 0 && tagno == td->tags_count) {
+ /*
+ * This must be the _untagged_ ANY type,
+ * which outermost tag isn't known in advance.
+ * Fetch the tag and length separately.
+ */
+ tag_len = ber_fetch_tag(ptr, size, &tlv_tag);
+ switch(tag_len) {
+ case -1: RETURN(RC_FAIL);
+ case 0: RETURN(RC_WMORE);
+ }
+ tlv_constr = BER_TLV_CONSTRUCTED(ptr);
+ len_len = ber_fetch_length(tlv_constr,
+ (const char *)ptr + tag_len, size - tag_len, &tlv_len);
+ switch(len_len) {
+ case -1: RETURN(RC_FAIL);
+ case 0: RETURN(RC_WMORE);
+ }
+ ASN_DEBUG("Advancing %ld in ANY case",
+ (long)(tag_len + len_len));
+ ADVANCE(tag_len + len_len);
+ } else {
+ assert(tagno < td->tags_count); /* At least one loop */
+ }
+ for((void)tagno; tagno < td->tags_count; tagno++, step++) {
+
+ /*
+ * Fetch and process T from TLV.
+ */
+ tag_len = ber_fetch_tag(ptr, size, &tlv_tag);
+ ASN_DEBUG("Fetching tag from {%p,%ld}: "
+ "len %ld, step %d, tagno %d got %s",
+ ptr, (long)size,
+ (long)tag_len, step, tagno,
+ ber_tlv_tag_string(tlv_tag));
+ switch(tag_len) {
+ case -1: RETURN(RC_FAIL);
+ case 0: RETURN(RC_WMORE);
+ }
+
+ tlv_constr = BER_TLV_CONSTRUCTED(ptr);
+
+ /*
+ * If {I}, don't check anything.
+ * If {I,B,C}, check B and C unless we're at I.
+ */
+ if(tag_mode != 0 && step == 0) {
+ /*
+ * We don't expect tag to match here.
+ * It's just because we don't know how the tag
+ * is supposed to look like.
+ */
+ } else {
+ assert(tagno >= 0); /* Guaranteed by the code above */
+ if(tlv_tag != td->tags[tagno]) {
+ /*
+ * Unexpected tag. Too bad.
+ */
+ ASN_DEBUG("Expected: %s, "
+ "expectation failed (tn=%d, tm=%d)",
+ ber_tlv_tag_string(td->tags[tagno]),
+ tagno, tag_mode
+ );
+ RETURN(RC_FAIL);
+ }
+ }
+
+ /*
+ * Attention: if there are more tags expected,
+ * ensure that the current tag is presented
+ * in constructed form (it contains other tags!).
+ * If this one is the last one, check that the tag form
+ * matches the one given in descriptor.
+ */
+ if(tagno < (td->tags_count - 1)) {
+ if(tlv_constr == 0) {
+ ASN_DEBUG("tlv_constr = %d, expfail",
+ tlv_constr);
+ RETURN(RC_FAIL);
+ }
+ } else {
+ if(last_tag_form != tlv_constr
+ && last_tag_form != -1) {
+ ASN_DEBUG("last_tag_form %d != %d",
+ last_tag_form, tlv_constr);
+ RETURN(RC_FAIL);
+ }
+ }
+
+ /*
+ * Fetch and process L from TLV.
+ */
+ len_len = ber_fetch_length(tlv_constr,
+ (const char *)ptr + tag_len, size - tag_len, &tlv_len);
+ ASN_DEBUG("Fetchinig len = %ld", (long)len_len);
+ switch(len_len) {
+ case -1: RETURN(RC_FAIL);
+ case 0: RETURN(RC_WMORE);
+ }
+
+ /*
+ * FIXME
+ * As of today, the chain of tags
+ * must either contain several indefinite length TLVs,
+ * or several definite length ones.
+ * No mixing is allowed.
+ */
+ if(tlv_len == -1) {
+ /*
+ * Indefinite length.
+ */
+ if(limit_len == -1) {
+ expect_00_terminators++;
+ } else {
+ ASN_DEBUG("Unexpected indefinite length "
+ "in a chain of definite lengths");
+ RETURN(RC_FAIL);
+ }
+ ADVANCE(tag_len + len_len);
+ continue;
+ } else {
+ if(expect_00_terminators) {
+ ASN_DEBUG("Unexpected definite length "
+ "in a chain of indefinite lengths");
+ RETURN(RC_FAIL);
+ }
+ }
+
+ /*
+ * Check that multiple TLVs specify ever decreasing length,
+ * which is consistent.
+ */
+ if(limit_len == -1) {
+ limit_len = tlv_len + tag_len + len_len;
+ if(limit_len < 0) {
+ /* Too great tlv_len value? */
+ RETURN(RC_FAIL);
+ }
+ } else if(limit_len != tlv_len + tag_len + len_len) {
+ /*
+ * Inner TLV specifies length which is inconsistent
+ * with the outer TLV's length value.
+ */
+ ASN_DEBUG("Outer TLV is %ld and inner is %ld",
+ (long)limit_len, (long)tlv_len);
+ RETURN(RC_FAIL);
+ }
+
+ ADVANCE(tag_len + len_len);
+
+ limit_len -= (tag_len + len_len);
+ if((ssize_t)size > limit_len) {
+ /*
+ * Make sure that we won't consume more bytes
+ * from the parent frame than the inferred limit.
+ */
+ size = limit_len;
+ }
+ }
+
+ if(opt_tlv_form)
+ *opt_tlv_form = tlv_constr;
+ if(expect_00_terminators)
+ *last_length = -expect_00_terminators;
+ else
+ *last_length = tlv_len;
+
+ RETURN(RC_OK);
+}
--- /dev/null
+/*-
+ * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#include <asn_internal.h>
+#include <ber_tlv_length.h>
+#include <ber_tlv_tag.h>
+
+ssize_t
+ber_fetch_length(int _is_constructed, const void *bufptr, size_t size,
+ ber_tlv_len_t *len_r) {
+ const uint8_t *buf = (const uint8_t *)bufptr;
+ unsigned oct;
+
+ if(size == 0)
+ return 0; /* Want more */
+
+ oct = *(const uint8_t *)buf;
+ if((oct & 0x80) == 0) {
+ /*
+ * Short definite length.
+ */
+ *len_r = oct; /* & 0x7F */
+ return 1;
+ } else {
+ ber_tlv_len_t len;
+ size_t skipped;
+
+ if(_is_constructed && oct == 0x80) {
+ *len_r = -1; /* Indefinite length */
+ return 1;
+ }
+
+ if(oct == 0xff) {
+ /* Reserved in standard for future use. */
+ return -1;
+ }
+
+ oct &= 0x7F; /* Leave only the 7 LS bits */
+ for(len = 0, buf++, skipped = 1;
+ oct && (++skipped <= size); buf++, oct--) {
+
+ len = (len << 8) | *buf;
+ if(len < 0
+ || (len >> ((8 * sizeof(len)) - 8) && oct > 1)) {
+ /*
+ * Too large length value.
+ */
+ return -1;
+ }
+ }
+
+ if(oct == 0) {
+ ber_tlv_len_t lenplusepsilon = (size_t)len + 1024;
+ /*
+ * Here length may be very close or equal to 2G.
+ * However, the arithmetics used in some decoders
+ * may add some (small) quantities to the length,
+ * to check the resulting value against some limits.
+ * This may result in integer wrap-around, which
+ * we try to avoid by checking it earlier here.
+ */
+ if(lenplusepsilon < 0) {
+ /* Too large length value */
+ return -1;
+ }
+
+ *len_r = len;
+ return skipped;
+ }
+
+ return 0; /* Want more */
+ }
+
+}
+
+ssize_t
+ber_skip_length(asn_codec_ctx_t *opt_codec_ctx,
+ int _is_constructed, const void *ptr, size_t size) {
+ ber_tlv_len_t vlen; /* Length of V in TLV */
+ ssize_t tl; /* Length of L in TLV */
+ ssize_t ll; /* Length of L in TLV */
+ size_t skip;
+
+ /*
+ * Make sure we didn't exceed the maximum stack size.
+ */
+ if(_ASN_STACK_OVERFLOW_CHECK(opt_codec_ctx))
+ return -1;
+
+ /*
+ * Determine the size of L in TLV.
+ */
+ ll = ber_fetch_length(_is_constructed, ptr, size, &vlen);
+ if(ll <= 0) return ll;
+
+ /*
+ * Definite length.
+ */
+ if(vlen >= 0) {
+ skip = ll + vlen;
+ if(skip > size)
+ return 0; /* Want more */
+ return skip;
+ }
+
+ /*
+ * Indefinite length!
+ */
+ ASN_DEBUG("Skipping indefinite length");
+ for(skip = ll, ptr = ((const char *)ptr) + ll, size -= ll;;) {
+ ber_tlv_tag_t tag;
+
+ /* Fetch the tag */
+ tl = ber_fetch_tag(ptr, size, &tag);
+ if(tl <= 0) return tl;
+
+ ll = ber_skip_length(opt_codec_ctx,
+ BER_TLV_CONSTRUCTED(ptr),
+ ((const char *)ptr) + tl, size - tl);
+ if(ll <= 0) return ll;
+
+ skip += tl + ll;
+
+ /*
+ * This may be the end of the indefinite length structure,
+ * two consecutive 0 octets.
+ * Check if it is true.
+ */
+ if(((const uint8_t *)ptr)[0] == 0
+ && ((const uint8_t *)ptr)[1] == 0)
+ return skip;
+
+ ptr = ((const char *)ptr) + tl + ll;
+ size -= tl + ll;
+ }
+
+ /* UNREACHABLE */
+}
+
+size_t
+der_tlv_length_serialize(ber_tlv_len_t len, void *bufp, size_t size) {
+ size_t required_size; /* Size of len encoding */
+ uint8_t *buf = (uint8_t *)bufp;
+ uint8_t *end;
+ size_t i;
+
+ if(len <= 127) {
+ /* Encoded in 1 octet */
+ if(size) *buf = (uint8_t)len;
+ return 1;
+ }
+
+ /*
+ * Compute the size of the subsequent bytes.
+ */
+ for(required_size = 1, i = 8; i < 8 * sizeof(len); i += 8) {
+ if(len >> i)
+ required_size++;
+ else
+ break;
+ }
+
+ if(size <= required_size)
+ return required_size + 1;
+
+ *buf++ = (uint8_t)(0x80 | required_size); /* Length of the encoding */
+
+ /*
+ * Produce the len encoding, space permitting.
+ */
+ end = buf + required_size;
+ for(i -= 8; buf < end; i -= 8, buf++)
+ *buf = (uint8_t)(len >> i);
+
+ return required_size + 1;
+}
+
--- /dev/null
+/*-
+ * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#include <asn_internal.h>
+#include <ber_tlv_tag.h>
+#include <errno.h>
+
+ssize_t
+ber_fetch_tag(const void *ptr, size_t size, ber_tlv_tag_t *tag_r) {
+ ber_tlv_tag_t val;
+ ber_tlv_tag_t tclass;
+ size_t skipped;
+
+ if(size == 0)
+ return 0;
+
+ val = *(const uint8_t *)ptr;
+ tclass = (val >> 6);
+ if((val &= 0x1F) != 0x1F) {
+ /*
+ * Simple form: everything encoded in a single octet.
+ * Tag Class is encoded using two least significant bits.
+ */
+ *tag_r = (val << 2) | tclass;
+ return 1;
+ }
+
+ /*
+ * Each octet contains 7 bits of useful information.
+ * The MSB is 0 if it is the last octet of the tag.
+ */
+ for(val = 0, ptr = ((const char *)ptr) + 1, skipped = 2;
+ skipped <= size;
+ ptr = ((const char *)ptr) + 1, skipped++) {
+ unsigned int oct = *(const uint8_t *)ptr;
+ if(oct & 0x80) {
+ val = (val << 7) | (oct & 0x7F);
+ /*
+ * Make sure there are at least 9 bits spare
+ * at the MS side of a value.
+ */
+ if(val >> ((8 * sizeof(val)) - 9)) {
+ /*
+ * We would not be able to accomodate
+ * any more tag bits.
+ */
+ return -1;
+ }
+ } else {
+ val = (val << 7) | oct;
+ *tag_r = (val << 2) | tclass;
+ return skipped;
+ }
+ }
+
+ return 0; /* Want more */
+}
+
+
+ssize_t
+ber_tlv_tag_fwrite(ber_tlv_tag_t tag, FILE *f) {
+ char buf[sizeof("[APPLICATION ]") + 32];
+ ssize_t ret;
+
+ ret = ber_tlv_tag_snprint(tag, buf, sizeof(buf));
+ if(ret >= (ssize_t)sizeof(buf) || ret < 2) {
+ errno = EPERM;
+ return -1;
+ }
+
+ return fwrite(buf, 1, ret, f);
+}
+
+ssize_t
+ber_tlv_tag_snprint(ber_tlv_tag_t tag, char *buf, size_t size) {
+ char *type = 0;
+ int ret;
+
+ switch(tag & 0x3) {
+ case ASN_TAG_CLASS_UNIVERSAL: type = "UNIVERSAL "; break;
+ case ASN_TAG_CLASS_APPLICATION: type = "APPLICATION "; break;
+ case ASN_TAG_CLASS_CONTEXT: type = ""; break;
+ case ASN_TAG_CLASS_PRIVATE: type = "PRIVATE "; break;
+ }
+
+ ret = snprintf(buf, size, "[%s%u]", type, ((unsigned)tag) >> 2);
+ if(ret <= 0 && size) buf[0] = '\0'; /* against broken libc's */
+
+ return ret;
+}
+
+char *
+ber_tlv_tag_string(ber_tlv_tag_t tag) {
+ static char buf[sizeof("[APPLICATION ]") + 32];
+
+ (void)ber_tlv_tag_snprint(tag, buf, sizeof(buf));
+
+ return buf;
+}
+
+
+size_t
+ber_tlv_tag_serialize(ber_tlv_tag_t tag, void *bufp, size_t size) {
+ int tclass = BER_TAG_CLASS(tag);
+ ber_tlv_tag_t tval = BER_TAG_VALUE(tag);
+ uint8_t *buf = (uint8_t *)bufp;
+ uint8_t *end;
+ size_t required_size;
+ size_t i;
+
+ if(tval <= 30) {
+ /* Encoded in 1 octet */
+ if(size) buf[0] = (tclass << 6) | tval;
+ return 1;
+ } else if(size) {
+ *buf++ = (tclass << 6) | 0x1F;
+ size--;
+ }
+
+ /*
+ * Compute the size of the subsequent bytes.
+ */
+ for(required_size = 1, i = 7; i < 8 * sizeof(tval); i += 7) {
+ if(tval >> i)
+ required_size++;
+ else
+ break;
+ }
+
+ if(size < required_size)
+ return required_size + 1;
+
+ /*
+ * Fill in the buffer, space permitting.
+ */
+ end = buf + required_size - 1;
+ for(i -= 7; buf < end; i -= 7, buf++)
+ *buf = 0x80 | ((tval >> i) & 0x7F);
+ *buf = (tval & 0x7F); /* Last octet without high bit */
+
+ return required_size + 1;
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2003, 2004, 2005, 2006 Lev Walkin <vlm@lionet.info>.
+ * All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#include <asn_internal.h>
+#include <constr_CHOICE.h>
+
+/*
+ * Number of bytes left for this structure.
+ * (ctx->left) indicates the number of bytes _transferred_ for the structure.
+ * (size) contains the number of bytes in the buffer passed.
+ */
+#define LEFT ((size<(size_t)ctx->left)?size:(size_t)ctx->left)
+
+/*
+ * If the subprocessor function returns with an indication that it wants
+ * more data, it may well be a fatal decoding problem, because the
+ * size is constrained by the <TLV>'s L, even if the buffer size allows
+ * reading more data.
+ * For example, consider the buffer containing the following TLVs:
+ * <T:5><L:1><V> <T:6>...
+ * The TLV length clearly indicates that one byte is expected in V, but
+ * if the V processor returns with "want more data" even if the buffer
+ * contains way more data than the V processor have seen.
+ */
+#define SIZE_VIOLATION (ctx->left >= 0 && (size_t)ctx->left <= size)
+
+/*
+ * This macro "eats" the part of the buffer which is definitely "consumed",
+ * i.e. was correctly converted into local representation or rightfully skipped.
+ */
+#undef ADVANCE
+#define ADVANCE(num_bytes) do { \
+ size_t num = num_bytes; \
+ ptr = ((const char *)ptr) + num;\
+ size -= num; \
+ if(ctx->left >= 0) \
+ ctx->left -= num; \
+ consumed_myself += num; \
+ } while(0)
+
+/*
+ * Switch to the next phase of parsing.
+ */
+#undef NEXT_PHASE
+#define NEXT_PHASE(ctx) do { \
+ ctx->phase++; \
+ ctx->step = 0; \
+ } while(0)
+
+/*
+ * Return a standardized complex structure.
+ */
+#undef RETURN
+#define RETURN(_code) do { \
+ rval.code = _code; \
+ rval.consumed = consumed_myself;\
+ return rval; \
+ } while(0)
+
+/*
+ * See the definitions.
+ */
+static int _fetch_present_idx(const void *struct_ptr, int off, int size);
+static void _set_present_idx(void *sptr, int offset, int size, int pres);
+
+/*
+ * Tags are canonically sorted in the tag to member table.
+ */
+static int
+_search4tag(const void *ap, const void *bp) {
+ const asn_TYPE_tag2member_t *a = (const asn_TYPE_tag2member_t *)ap;
+ const asn_TYPE_tag2member_t *b = (const asn_TYPE_tag2member_t *)bp;
+
+ int a_class = BER_TAG_CLASS(a->el_tag);
+ int b_class = BER_TAG_CLASS(b->el_tag);
+
+ if(a_class == b_class) {
+ ber_tlv_tag_t a_value = BER_TAG_VALUE(a->el_tag);
+ ber_tlv_tag_t b_value = BER_TAG_VALUE(b->el_tag);
+
+ if(a_value == b_value)
+ return 0;
+ else if(a_value < b_value)
+ return -1;
+ else
+ return 1;
+ } else if(a_class < b_class) {
+ return -1;
+ } else {
+ return 1;
+ }
+}
+
+/*
+ * The decoder of the CHOICE type.
+ */
+asn_dec_rval_t
+CHOICE_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ void **struct_ptr, const void *ptr, size_t size, int tag_mode) {
+ /*
+ * Bring closer parts of structure description.
+ */
+ asn_CHOICE_specifics_t *specs = (asn_CHOICE_specifics_t *)td->specifics;
+ asn_TYPE_member_t *elements = td->elements;
+
+ /*
+ * Parts of the structure being constructed.
+ */
+ void *st = *struct_ptr; /* Target structure. */
+ asn_struct_ctx_t *ctx; /* Decoder context */
+
+ ber_tlv_tag_t tlv_tag; /* T from TLV */
+ ssize_t tag_len; /* Length of TLV's T */
+ asn_dec_rval_t rval; /* Return code from subparsers */
+
+ ssize_t consumed_myself = 0; /* Consumed bytes from ptr */
+
+ ASN_DEBUG("Decoding %s as CHOICE", td->name);
+
+ /*
+ * Create the target structure if it is not present already.
+ */
+ if(st == 0) {
+ st = *struct_ptr = CALLOC(1, specs->struct_size);
+ if(st == 0) {
+ RETURN(RC_FAIL);
+ }
+ }
+
+ /*
+ * Restore parsing context.
+ */
+ ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset);
+
+ /*
+ * Start to parse where left previously
+ */
+ switch(ctx->phase) {
+ case 0:
+ /*
+ * PHASE 0.
+ * Check that the set of tags associated with given structure
+ * perfectly fits our expectations.
+ */
+
+ if(tag_mode || td->tags_count) {
+ rval = ber_check_tags(opt_codec_ctx, td, ctx, ptr, size,
+ tag_mode, -1, &ctx->left, 0);
+ if(rval.code != RC_OK) {
+ ASN_DEBUG("%s tagging check failed: %d",
+ td->name, rval.code);
+ return rval;
+ }
+
+ if(ctx->left >= 0) {
+ /* ?Substracted below! */
+ ctx->left += rval.consumed;
+ }
+ ADVANCE(rval.consumed);
+ } else {
+ ctx->left = -1;
+ }
+
+ NEXT_PHASE(ctx);
+
+ ASN_DEBUG("Structure consumes %ld bytes, buffer %ld",
+ (long)ctx->left, (long)size);
+
+ /* Fall through */
+ case 1:
+ /*
+ * Fetch the T from TLV.
+ */
+ tag_len = ber_fetch_tag(ptr, LEFT, &tlv_tag);
+ ASN_DEBUG("In %s CHOICE tag length %d", td->name, (int)tag_len);
+ switch(tag_len) {
+ case 0: if(!SIZE_VIOLATION) RETURN(RC_WMORE);
+ /* Fall through */
+ case -1: RETURN(RC_FAIL);
+ }
+
+ do {
+ asn_TYPE_tag2member_t *t2m;
+ asn_TYPE_tag2member_t key;
+
+ key.el_tag = tlv_tag;
+ t2m = (asn_TYPE_tag2member_t *)bsearch(&key,
+ specs->tag2el, specs->tag2el_count,
+ sizeof(specs->tag2el[0]), _search4tag);
+ if(t2m) {
+ /*
+ * Found the element corresponding to the tag.
+ */
+ NEXT_PHASE(ctx);
+ ctx->step = t2m->el_no;
+ break;
+ } else if(specs->ext_start == -1) {
+ ASN_DEBUG("Unexpected tag %s "
+ "in non-extensible CHOICE %s",
+ ber_tlv_tag_string(tlv_tag), td->name);
+ RETURN(RC_FAIL);
+ } else {
+ /* Skip this tag */
+ ssize_t skip;
+
+ ASN_DEBUG("Skipping unknown tag %s",
+ ber_tlv_tag_string(tlv_tag));
+
+ skip = ber_skip_length(opt_codec_ctx,
+ BER_TLV_CONSTRUCTED(ptr),
+ (const char *)ptr + tag_len,
+ LEFT - tag_len);
+
+ switch(skip) {
+ case 0: if(!SIZE_VIOLATION) RETURN(RC_WMORE);
+ /* Fall through */
+ case -1: RETURN(RC_FAIL);
+ }
+
+ ADVANCE(skip + tag_len);
+ RETURN(RC_OK);
+ }
+ } while(0);
+
+ case 2:
+ /*
+ * PHASE 2.
+ * Read in the element.
+ */
+ do {
+ asn_TYPE_member_t *elm;/* CHOICE's element */
+ void *memb_ptr; /* Pointer to the member */
+ void **memb_ptr2; /* Pointer to that pointer */
+
+ elm = &elements[ctx->step];
+
+ /*
+ * Compute the position of the member inside a structure,
+ * and also a type of containment (it may be contained
+ * as pointer or using inline inclusion).
+ */
+ if(elm->flags & ATF_POINTER) {
+ /* Member is a pointer to another structure */
+ memb_ptr2 = (void **)((char *)st + elm->memb_offset);
+ } else {
+ /*
+ * A pointer to a pointer
+ * holding the start of the structure
+ */
+ memb_ptr = (char *)st + elm->memb_offset;
+ memb_ptr2 = &memb_ptr;
+ }
+ /* Set presence to be able to free it properly at any time */
+ _set_present_idx(st, specs->pres_offset,
+ specs->pres_size, ctx->step + 1);
+ /*
+ * Invoke the member fetch routine according to member's type
+ */
+ rval = elm->type->ber_decoder(opt_codec_ctx, elm->type,
+ memb_ptr2, ptr, LEFT, elm->tag_mode);
+ switch(rval.code) {
+ case RC_OK:
+ break;
+ case RC_WMORE: /* More data expected */
+ if(!SIZE_VIOLATION) {
+ ADVANCE(rval.consumed);
+ RETURN(RC_WMORE);
+ }
+ RETURN(RC_FAIL);
+ case RC_FAIL: /* Fatal error */
+ RETURN(rval.code);
+ } /* switch(rval) */
+
+ ADVANCE(rval.consumed);
+ } while(0);
+
+ NEXT_PHASE(ctx);
+
+ /* Fall through */
+ case 3:
+ ASN_DEBUG("CHOICE %s Leftover: %ld, size = %ld, tm=%d, tc=%d",
+ td->name, (long)ctx->left, (long)size,
+ tag_mode, td->tags_count);
+
+ if(ctx->left > 0) {
+ /*
+ * The type must be fully decoded
+ * by the CHOICE member-specific decoder.
+ */
+ RETURN(RC_FAIL);
+ }
+
+ if(ctx->left == -1
+ && !(tag_mode || td->tags_count)) {
+ /*
+ * This is an untagged CHOICE.
+ * It doesn't contain nothing
+ * except for the member itself, including all its tags.
+ * The decoding is completed.
+ */
+ NEXT_PHASE(ctx);
+ break;
+ }
+
+ /*
+ * Read in the "end of data chunks"'s.
+ */
+ while(ctx->left < 0) {
+ ssize_t tl;
+
+ tl = ber_fetch_tag(ptr, LEFT, &tlv_tag);
+ switch(tl) {
+ case 0: if(!SIZE_VIOLATION) RETURN(RC_WMORE);
+ /* Fall through */
+ case -1: RETURN(RC_FAIL);
+ }
+
+ /*
+ * Expected <0><0>...
+ */
+ if(((const uint8_t *)ptr)[0] == 0) {
+ if(LEFT < 2) {
+ if(SIZE_VIOLATION)
+ RETURN(RC_FAIL);
+ else
+ RETURN(RC_WMORE);
+ } else if(((const uint8_t *)ptr)[1] == 0) {
+ /*
+ * Correctly finished with <0><0>.
+ */
+ ADVANCE(2);
+ ctx->left++;
+ continue;
+ }
+ } else {
+ ASN_DEBUG("Unexpected continuation in %s",
+ td->name);
+ RETURN(RC_FAIL);
+ }
+
+ /* UNREACHABLE */
+ }
+
+ NEXT_PHASE(ctx);
+ case 4:
+ /* No meaningful work here */
+ break;
+ }
+
+ RETURN(RC_OK);
+}
+
+asn_enc_rval_t
+CHOICE_encode_der(asn_TYPE_descriptor_t *td, void *sptr,
+ int tag_mode, ber_tlv_tag_t tag,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ asn_CHOICE_specifics_t *specs = (asn_CHOICE_specifics_t *)td->specifics;
+ asn_TYPE_member_t *elm; /* CHOICE element */
+ asn_enc_rval_t erval;
+ void *memb_ptr;
+ size_t computed_size = 0;
+ int present;
+
+ if(!sptr) _ASN_ENCODE_FAILED;
+
+ ASN_DEBUG("%s %s as CHOICE",
+ cb?"Encoding":"Estimating", td->name);
+
+ present = _fetch_present_idx(sptr,
+ specs->pres_offset, specs->pres_size);
+
+ /*
+ * If the structure was not initialized, it cannot be encoded:
+ * can't deduce what to encode in the choice type.
+ */
+ if(present <= 0 || present > td->elements_count) {
+ if(present == 0 && td->elements_count == 0) {
+ /* The CHOICE is empty?! */
+ erval.encoded = 0;
+ _ASN_ENCODED_OK(erval);
+ }
+ _ASN_ENCODE_FAILED;
+ }
+
+ /*
+ * Seek over the present member of the structure.
+ */
+ elm = &td->elements[present-1];
+ if(elm->flags & ATF_POINTER) {
+ memb_ptr = *(void **)((char *)sptr + elm->memb_offset);
+ if(memb_ptr == 0) {
+ if(elm->optional) {
+ erval.encoded = 0;
+ _ASN_ENCODED_OK(erval);
+ }
+ /* Mandatory element absent */
+ _ASN_ENCODE_FAILED;
+ }
+ } else {
+ memb_ptr = (void *)((char *)sptr + elm->memb_offset);
+ }
+
+ /*
+ * If the CHOICE itself is tagged EXPLICIT:
+ * T ::= [2] EXPLICIT CHOICE { ... }
+ * Then emit the appropriate tags.
+ */
+ if(tag_mode == 1 || td->tags_count) {
+ /*
+ * For this, we need to pre-compute the member.
+ */
+ ssize_t ret;
+
+ /* Encode member with its tag */
+ erval = elm->type->der_encoder(elm->type, memb_ptr,
+ elm->tag_mode, elm->tag, 0, 0);
+ if(erval.encoded == -1)
+ return erval;
+
+ /* Encode CHOICE with parent or my own tag */
+ ret = der_write_tags(td, erval.encoded, tag_mode, 1, tag,
+ cb, app_key);
+ if(ret == -1)
+ _ASN_ENCODE_FAILED;
+ computed_size += ret;
+ }
+
+ /*
+ * Encode the single underlying member.
+ */
+ erval = elm->type->der_encoder(elm->type, memb_ptr,
+ elm->tag_mode, elm->tag, cb, app_key);
+ if(erval.encoded == -1)
+ return erval;
+
+ ASN_DEBUG("Encoded CHOICE member in %ld bytes (+%ld)",
+ (long)erval.encoded, (long)computed_size);
+
+ erval.encoded += computed_size;
+
+ return erval;
+}
+
+ber_tlv_tag_t
+CHOICE_outmost_tag(asn_TYPE_descriptor_t *td, const void *ptr, int tag_mode, ber_tlv_tag_t tag) {
+ asn_CHOICE_specifics_t *specs = (asn_CHOICE_specifics_t *)td->specifics;
+ int present;
+
+ assert(tag_mode == 0); (void)tag_mode;
+ assert(tag == 0); (void)tag;
+
+ /*
+ * Figure out which CHOICE element is encoded.
+ */
+ present = _fetch_present_idx(ptr, specs->pres_offset, specs->pres_size);
+
+ if(present > 0 || present <= td->elements_count) {
+ asn_TYPE_member_t *elm = &td->elements[present-1];
+ const void *memb_ptr;
+
+ if(elm->flags & ATF_POINTER) {
+ memb_ptr = *(const void * const *)
+ ((const char *)ptr + elm->memb_offset);
+ } else {
+ memb_ptr = (const void *)
+ ((const char *)ptr + elm->memb_offset);
+ }
+
+ return asn_TYPE_outmost_tag(elm->type, memb_ptr,
+ elm->tag_mode, elm->tag);
+ } else {
+ return (ber_tlv_tag_t)-1;
+ }
+}
+
+int
+CHOICE_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
+ asn_app_constraint_failed_f *ctfailcb, void *app_key) {
+ asn_CHOICE_specifics_t *specs = (asn_CHOICE_specifics_t *)td->specifics;
+ int present;
+
+ if(!sptr) {
+ _ASN_CTFAIL(app_key, td,
+ "%s: value not given (%s:%d)",
+ td->name, __FILE__, __LINE__);
+ return -1;
+ }
+
+ /*
+ * Figure out which CHOICE element is encoded.
+ */
+ present = _fetch_present_idx(sptr, specs->pres_offset,specs->pres_size);
+ if(present > 0 && present <= td->elements_count) {
+ asn_TYPE_member_t *elm = &td->elements[present-1];
+ const void *memb_ptr;
+
+ if(elm->flags & ATF_POINTER) {
+ memb_ptr = *(const void * const *)((const char *)sptr + elm->memb_offset);
+ if(!memb_ptr) {
+ if(elm->optional)
+ return 0;
+ _ASN_CTFAIL(app_key, td,
+ "%s: mandatory CHOICE element %s absent (%s:%d)",
+ td->name, elm->name, __FILE__, __LINE__);
+ return -1;
+ }
+ } else {
+ memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
+ }
+
+ if(elm->memb_constraints) {
+ return elm->memb_constraints(elm->type, memb_ptr,
+ ctfailcb, app_key);
+ } else {
+ int ret = elm->type->check_constraints(elm->type,
+ memb_ptr, ctfailcb, app_key);
+ /*
+ * Cannot inherit it eralier:
+ * need to make sure we get the updated version.
+ */
+ elm->memb_constraints = elm->type->check_constraints;
+ return ret;
+ }
+ } else {
+ _ASN_CTFAIL(app_key, td,
+ "%s: no CHOICE element given (%s:%d)",
+ td->name, __FILE__, __LINE__);
+ return -1;
+ }
+}
+
+#undef XER_ADVANCE
+#define XER_ADVANCE(num_bytes) do { \
+ size_t num = num_bytes; \
+ buf_ptr = ((const char *)buf_ptr) + num;\
+ size -= num; \
+ consumed_myself += num; \
+ } while(0)
+
+/*
+ * Decode the XER (XML) data.
+ */
+asn_dec_rval_t
+CHOICE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ void **struct_ptr, const char *opt_mname,
+ const void *buf_ptr, size_t size) {
+ /*
+ * Bring closer parts of structure description.
+ */
+ asn_CHOICE_specifics_t *specs = (asn_CHOICE_specifics_t *)td->specifics;
+ const char *xml_tag = opt_mname ? opt_mname : td->xml_tag;
+
+ /*
+ * Parts of the structure being constructed.
+ */
+ void *st = *struct_ptr; /* Target structure. */
+ asn_struct_ctx_t *ctx; /* Decoder context */
+
+ asn_dec_rval_t rval; /* Return value of a decoder */
+ ssize_t consumed_myself = 0; /* Consumed bytes from ptr */
+ int edx; /* Element index */
+
+ /*
+ * Create the target structure if it is not present already.
+ */
+ if(st == 0) {
+ st = *struct_ptr = CALLOC(1, specs->struct_size);
+ if(st == 0) RETURN(RC_FAIL);
+ }
+
+ /*
+ * Restore parsing context.
+ */
+ ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset);
+ if(ctx->phase == 0 && !*xml_tag)
+ ctx->phase = 1; /* Skip the outer tag checking phase */
+
+ /*
+ * Phases of XER/XML processing:
+ * Phase 0: Check that the opening tag matches our expectations.
+ * Phase 1: Processing body and reacting on closing tag.
+ * Phase 2: Processing inner type.
+ * Phase 3: Only waiting for closing tag.
+ * Phase 4: Skipping unknown extensions.
+ * Phase 5: PHASED OUT
+ */
+ for(edx = ctx->step; ctx->phase <= 4;) {
+ pxer_chunk_type_e ch_type; /* XER chunk type */
+ ssize_t ch_size; /* Chunk size */
+ xer_check_tag_e tcv; /* Tag check value */
+ asn_TYPE_member_t *elm;
+
+ /*
+ * Go inside the member.
+ */
+ if(ctx->phase == 2) {
+ asn_dec_rval_t tmprval;
+ void *memb_ptr; /* Pointer to the member */
+ void **memb_ptr2; /* Pointer to that pointer */
+
+ elm = &td->elements[edx];
+
+ if(elm->flags & ATF_POINTER) {
+ /* Member is a pointer to another structure */
+ memb_ptr2 = (void **)((char *)st
+ + elm->memb_offset);
+ } else {
+ memb_ptr = (char *)st + elm->memb_offset;
+ memb_ptr2 = &memb_ptr;
+ }
+
+ /* Start/Continue decoding the inner member */
+ tmprval = elm->type->xer_decoder(opt_codec_ctx,
+ elm->type, memb_ptr2, elm->name,
+ buf_ptr, size);
+ XER_ADVANCE(tmprval.consumed);
+ ASN_DEBUG("XER/CHOICE: itdf: [%s] code=%d",
+ elm->type->name, tmprval.code);
+ if(tmprval.code != RC_OK)
+ RETURN(tmprval.code);
+ assert(_fetch_present_idx(st,
+ specs->pres_offset, specs->pres_size) == 0);
+ /* Record what we've got */
+ _set_present_idx(st,
+ specs->pres_offset, specs->pres_size, edx + 1);
+ ctx->phase = 3;
+ /* Fall through */
+ }
+
+ /* No need to wait for closing tag; special mode. */
+ if(ctx->phase == 3 && !*xml_tag) {
+ ctx->phase = 5; /* Phase out */
+ RETURN(RC_OK);
+ }
+
+ /*
+ * Get the next part of the XML stream.
+ */
+ ch_size = xer_next_token(&ctx->context, buf_ptr, size, &ch_type);
+ switch(ch_size) {
+ case -1: RETURN(RC_FAIL);
+ case 0: RETURN(RC_WMORE);
+ default:
+ switch(ch_type) {
+ case PXER_COMMENT: /* Got XML comment */
+ case PXER_TEXT: /* Ignore free-standing text */
+ XER_ADVANCE(ch_size); /* Skip silently */
+ continue;
+ case PXER_TAG:
+ break; /* Check the rest down there */
+ }
+ }
+
+ tcv = xer_check_tag(buf_ptr, ch_size, xml_tag);
+ ASN_DEBUG("XER/CHOICE checked [%c%c%c%c] vs [%s], tcv=%d",
+ ch_size>0?((const uint8_t *)buf_ptr)[0]:'?',
+ ch_size>1?((const uint8_t *)buf_ptr)[1]:'?',
+ ch_size>2?((const uint8_t *)buf_ptr)[2]:'?',
+ ch_size>3?((const uint8_t *)buf_ptr)[3]:'?',
+ xml_tag, tcv);
+
+ /* Skip the extensions section */
+ if(ctx->phase == 4) {
+ ASN_DEBUG("skip_unknown(%d, %ld)",
+ tcv, (long)ctx->left);
+ switch(xer_skip_unknown(tcv, &ctx->left)) {
+ case -1:
+ ctx->phase = 5;
+ RETURN(RC_FAIL);
+ continue;
+ case 1:
+ ctx->phase = 3;
+ /* Fall through */
+ case 0:
+ XER_ADVANCE(ch_size);
+ continue;
+ case 2:
+ ctx->phase = 3;
+ break;
+ }
+ }
+
+ switch(tcv) {
+ case XCT_BOTH:
+ break; /* No CHOICE? */
+ case XCT_CLOSING:
+ if(ctx->phase != 3)
+ break;
+ XER_ADVANCE(ch_size);
+ ctx->phase = 5; /* Phase out */
+ RETURN(RC_OK);
+ case XCT_OPENING:
+ if(ctx->phase == 0) {
+ XER_ADVANCE(ch_size);
+ ctx->phase = 1; /* Processing body phase */
+ continue;
+ }
+ /* Fall through */
+ case XCT_UNKNOWN_OP:
+ case XCT_UNKNOWN_BO:
+
+ if(ctx->phase != 1)
+ break; /* Really unexpected */
+
+ /*
+ * Search which inner member corresponds to this tag.
+ */
+ for(edx = 0; edx < td->elements_count; edx++) {
+ elm = &td->elements[edx];
+ tcv = xer_check_tag(buf_ptr,ch_size,elm->name);
+ switch(tcv) {
+ case XCT_BOTH:
+ case XCT_OPENING:
+ /*
+ * Process this member.
+ */
+ ctx->step = edx;
+ ctx->phase = 2;
+ break;
+ case XCT_UNKNOWN_OP:
+ case XCT_UNKNOWN_BO:
+ continue;
+ default:
+ edx = td->elements_count;
+ break; /* Phase out */
+ }
+ break;
+ }
+ if(edx != td->elements_count)
+ continue;
+
+ /* It is expected extension */
+ if(specs->ext_start != -1) {
+ ASN_DEBUG("Got anticipated extension");
+ /*
+ * Check for (XCT_BOTH or XCT_UNKNOWN_BO)
+ * By using a mask. Only record a pure
+ * <opening> tags.
+ */
+ if(tcv & XCT_CLOSING) {
+ /* Found </extension> without body */
+ ctx->phase = 3; /* Terminating */
+ } else {
+ ctx->left = 1;
+ ctx->phase = 4; /* Skip ...'s */
+ }
+ XER_ADVANCE(ch_size);
+ continue;
+ }
+
+ /* Fall through */
+ default:
+ break;
+ }
+
+ ASN_DEBUG("Unexpected XML tag [%c%c%c%c] in CHOICE [%s]"
+ " (ph=%d, tag=%s)",
+ ch_size>0?((const uint8_t *)buf_ptr)[0]:'?',
+ ch_size>1?((const uint8_t *)buf_ptr)[1]:'?',
+ ch_size>2?((const uint8_t *)buf_ptr)[2]:'?',
+ ch_size>3?((const uint8_t *)buf_ptr)[3]:'?',
+ td->name, ctx->phase, xml_tag);
+ break;
+ }
+
+ ctx->phase = 5; /* Phase out, just in case */
+ RETURN(RC_FAIL);
+}
+
+
+asn_enc_rval_t
+CHOICE_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ asn_CHOICE_specifics_t *specs=(asn_CHOICE_specifics_t *)td->specifics;
+ asn_enc_rval_t er;
+ int present;
+
+ if(!sptr)
+ _ASN_ENCODE_FAILED;
+
+ /*
+ * Figure out which CHOICE element is encoded.
+ */
+ present = _fetch_present_idx(sptr, specs->pres_offset,specs->pres_size);
+
+ if(present <= 0 || present > td->elements_count) {
+ _ASN_ENCODE_FAILED;
+ } else {
+ asn_enc_rval_t tmper;
+ asn_TYPE_member_t *elm = &td->elements[present-1];
+ void *memb_ptr;
+ const char *mname = elm->name;
+ unsigned int mlen = strlen(mname);
+
+ if(elm->flags & ATF_POINTER) {
+ memb_ptr = *(void **)((char *)sptr + elm->memb_offset);
+ if(!memb_ptr) _ASN_ENCODE_FAILED;
+ } else {
+ memb_ptr = (void *)((char *)sptr + elm->memb_offset);
+ }
+
+ er.encoded = 0;
+
+ if(!(flags & XER_F_CANONICAL)) _i_ASN_TEXT_INDENT(1, ilevel);
+ _ASN_CALLBACK3("<", 1, mname, mlen, ">", 1);
+
+ tmper = elm->type->xer_encoder(elm->type, memb_ptr,
+ ilevel + 1, flags, cb, app_key);
+ if(tmper.encoded == -1) return tmper;
+
+ _ASN_CALLBACK3("</", 2, mname, mlen, ">", 1);
+
+ er.encoded += 5 + (2 * mlen) + tmper.encoded;
+ }
+
+ if(!(flags & XER_F_CANONICAL)) _i_ASN_TEXT_INDENT(1, ilevel - 1);
+
+ _ASN_ENCODED_OK(er);
+cb_failed:
+ _ASN_ENCODE_FAILED;
+}
+
+asn_dec_rval_t
+CHOICE_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
+ asn_CHOICE_specifics_t *specs = (asn_CHOICE_specifics_t *)td->specifics;
+ asn_dec_rval_t rv;
+ asn_per_constraint_t *ct;
+ asn_TYPE_member_t *elm; /* CHOICE's element */
+ void *memb_ptr;
+ void **memb_ptr2;
+ void *st = *sptr;
+ int value;
+
+ if(_ASN_STACK_OVERFLOW_CHECK(opt_codec_ctx))
+ _ASN_DECODE_FAILED;
+
+ /*
+ * Create the target structure if it is not present already.
+ */
+ if(!st) {
+ st = *sptr = CALLOC(1, specs->struct_size);
+ if(!st) _ASN_DECODE_FAILED;
+ }
+
+ if(constraints) ct = &constraints->value;
+ else if(td->per_constraints) ct = &td->per_constraints->value;
+ else ct = 0;
+
+ if(ct && ct->flags & APC_EXTENSIBLE) {
+ value = per_get_few_bits(pd, 1);
+ if(value < 0) _ASN_DECODE_STARVED;
+ if(value) ct = 0; /* Not restricted */
+ }
+
+ if(ct && ct->range_bits >= 0) {
+ value = per_get_few_bits(pd, ct->range_bits);
+ if(value < 0) _ASN_DECODE_STARVED;
+ ASN_DEBUG("CHOICE %s got index %d in range %d",
+ td->name, value, ct->range_bits);
+ if(value > ct->upper_bound)
+ _ASN_DECODE_FAILED;
+ } else {
+ if(specs->ext_start == -1)
+ _ASN_DECODE_FAILED;
+ value = uper_get_nsnnwn(pd);
+ if(value < 0) _ASN_DECODE_STARVED;
+ value += specs->ext_start;
+ if(value >= td->elements_count)
+ _ASN_DECODE_FAILED;
+ ASN_DEBUG("NOT IMPLEMENTED YET");
+ _ASN_DECODE_FAILED;
+ }
+
+ /* Adjust if canonical order is different from natural order */
+ if(specs->canonical_order)
+ value = specs->canonical_order[value];
+
+ /* Set presence to be able to free it later */
+ _set_present_idx(st, specs->pres_offset, specs->pres_size, value + 1);
+
+ elm = &td->elements[value];
+ if(elm->flags & ATF_POINTER) {
+ /* Member is a pointer to another structure */
+ memb_ptr2 = (void **)((char *)st + elm->memb_offset);
+ } else {
+ memb_ptr = (char *)st + elm->memb_offset;
+ memb_ptr2 = &memb_ptr;
+ }
+ ASN_DEBUG("Discovered CHOICE %s encodes %s", td->name, elm->name);
+
+ rv = elm->type->uper_decoder(opt_codec_ctx, elm->type,
+ elm->per_constraints, memb_ptr2, pd);
+ if(rv.code != RC_OK)
+ ASN_DEBUG("Failed to decode %s in %s (CHOICE)",
+ elm->name, td->name);
+ return rv;
+}
+
+asn_enc_rval_t
+CHOICE_encode_uper(asn_TYPE_descriptor_t *td,
+ asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
+ asn_CHOICE_specifics_t *specs = (asn_CHOICE_specifics_t *)td->specifics;
+ asn_TYPE_member_t *elm; /* CHOICE's element */
+ asn_per_constraint_t *ct;
+ void *memb_ptr;
+ int present;
+
+ if(!sptr) _ASN_ENCODE_FAILED;
+
+ ASN_DEBUG("Encoding %s as CHOICE", td->name);
+
+ if(constraints) ct = &constraints->value;
+ else if(td->per_constraints) ct = &td->per_constraints->value;
+ else ct = 0;
+
+ present = _fetch_present_idx(sptr,
+ specs->pres_offset, specs->pres_size);
+
+ /*
+ * If the structure was not initialized properly, it cannot be encoded:
+ * can't deduce what to encode in the choice type.
+ */
+ if(present <= 0 || present > td->elements_count)
+ _ASN_ENCODE_FAILED;
+ else
+ present--;
+
+ /* Adjust if canonical order is different from natural order */
+ if(specs->canonical_order)
+ present = specs->canonical_order[present];
+
+ ASN_DEBUG("Encoding %s CHOICE element %d", td->name, present);
+
+ if(ct && ct->range_bits >= 0) {
+ if(present < ct->lower_bound
+ || present > ct->upper_bound) {
+ if(ct->flags & APC_EXTENSIBLE) {
+ if(per_put_few_bits(po, 1, 1))
+ _ASN_ENCODE_FAILED;
+ } else {
+ _ASN_ENCODE_FAILED;
+ }
+ ct = 0;
+ }
+ }
+ if(ct && ct->flags & APC_EXTENSIBLE)
+ if(per_put_few_bits(po, 0, 1))
+ _ASN_ENCODE_FAILED;
+
+ if(ct && ct->range_bits >= 0) {
+ if(per_put_few_bits(po, present, ct->range_bits))
+ _ASN_ENCODE_FAILED;
+ } else {
+ if(specs->ext_start == -1)
+ _ASN_ENCODE_FAILED;
+ if(uper_put_nsnnwn(po, present - specs->ext_start))
+ _ASN_ENCODE_FAILED;
+ ASN_DEBUG("NOT IMPLEMENTED YET");
+ _ASN_ENCODE_FAILED;
+ }
+
+ elm = &td->elements[present];
+ if(elm->flags & ATF_POINTER) {
+ /* Member is a pointer to another structure */
+ memb_ptr = *(void **)((char *)sptr + elm->memb_offset);
+ if(!memb_ptr) _ASN_ENCODE_FAILED;
+ } else {
+ memb_ptr = (char *)sptr + elm->memb_offset;
+ }
+
+ return elm->type->uper_encoder(elm->type, elm->per_constraints,
+ memb_ptr, po);
+}
+
+
+int
+CHOICE_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ asn_CHOICE_specifics_t *specs = (asn_CHOICE_specifics_t *)td->specifics;
+ int present;
+
+ if(!sptr) return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
+
+ /*
+ * Figure out which CHOICE element is encoded.
+ */
+ present = _fetch_present_idx(sptr, specs->pres_offset,specs->pres_size);
+
+ /*
+ * Print that element.
+ */
+ if(present > 0 && present <= td->elements_count) {
+ asn_TYPE_member_t *elm = &td->elements[present-1];
+ const void *memb_ptr;
+
+ if(elm->flags & ATF_POINTER) {
+ memb_ptr = *(const void * const *)((const char *)sptr + elm->memb_offset);
+ if(!memb_ptr) return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
+ } else {
+ memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
+ }
+
+ /* Print member's name and stuff */
+ if(0) {
+ if(cb(elm->name, strlen(elm->name), app_key) < 0
+ || cb(": ", 2, app_key) < 0)
+ return -1;
+ }
+
+ return elm->type->print_struct(elm->type, memb_ptr, ilevel,
+ cb, app_key);
+ } else {
+ return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
+ }
+}
+
+void
+CHOICE_free(asn_TYPE_descriptor_t *td, void *ptr, int contents_only) {
+ asn_CHOICE_specifics_t *specs = (asn_CHOICE_specifics_t *)td->specifics;
+ int present;
+
+ if(!td || !ptr)
+ return;
+
+ ASN_DEBUG("Freeing %s as CHOICE", td->name);
+
+ /*
+ * Figure out which CHOICE element is encoded.
+ */
+ present = _fetch_present_idx(ptr, specs->pres_offset, specs->pres_size);
+
+ /*
+ * Free that element.
+ */
+ if(present > 0 && present <= td->elements_count) {
+ asn_TYPE_member_t *elm = &td->elements[present-1];
+ void *memb_ptr;
+
+ if(elm->flags & ATF_POINTER) {
+ memb_ptr = *(void **)((char *)ptr + elm->memb_offset);
+ if(memb_ptr)
+ ASN_STRUCT_FREE(*elm->type, memb_ptr);
+ } else {
+ memb_ptr = (void *)((char *)ptr + elm->memb_offset);
+ ASN_STRUCT_FREE_CONTENTS_ONLY(*elm->type, memb_ptr);
+ }
+ }
+
+ if(!contents_only) {
+ FREEMEM(ptr);
+ }
+}
+
+
+/*
+ * The following functions functions offer protection against -fshort-enums,
+ * compatible with little- and big-endian machines.
+ * If assertion is triggered, either disable -fshort-enums, or add an entry
+ * here with the ->pres_size of your target stracture.
+ * Unless the target structure is packed, the ".present" member
+ * is guaranteed to be aligned properly. ASN.1 compiler itself does not
+ * produce packed code.
+ */
+static int
+_fetch_present_idx(const void *struct_ptr, int pres_offset, int pres_size) {
+ const void *present_ptr;
+ int present;
+
+ present_ptr = ((const char *)struct_ptr) + pres_offset;
+
+ switch(pres_size) {
+ case sizeof(int): present = *(const int *)present_ptr; break;
+ case sizeof(short): present = *(const short *)present_ptr; break;
+ case sizeof(char): present = *(const char *)present_ptr; break;
+ default:
+ /* ANSI C mandates enum to be equivalent to integer */
+ assert(pres_size != sizeof(int));
+ return 0; /* If not aborted, pass back safe value */
+ }
+
+ return present;
+}
+
+static void
+_set_present_idx(void *struct_ptr, int pres_offset, int pres_size, int present) {
+ void *present_ptr;
+ present_ptr = ((char *)struct_ptr) + pres_offset;
+
+ switch(pres_size) {
+ case sizeof(int): *(int *)present_ptr = present; break;
+ case sizeof(short): *(short *)present_ptr = present; break;
+ case sizeof(char): *(char *)present_ptr = present; break;
+ default:
+ /* ANSI C mandates enum to be equivalent to integer */
+ assert(pres_size != sizeof(int));
+ }
+}
--- /dev/null
+/*-
+ * Copyright (c) 2003, 2004, 2005, 2006 Lev Walkin <vlm@lionet.info>.
+ * All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#include <asn_internal.h>
+#include <constr_SEQUENCE.h>
+
+/*
+ * Number of bytes left for this structure.
+ * (ctx->left) indicates the number of bytes _transferred_ for the structure.
+ * (size) contains the number of bytes in the buffer passed.
+ */
+#define LEFT ((size<(size_t)ctx->left)?size:(size_t)ctx->left)
+
+/*
+ * If the subprocessor function returns with an indication that it wants
+ * more data, it may well be a fatal decoding problem, because the
+ * size is constrained by the <TLV>'s L, even if the buffer size allows
+ * reading more data.
+ * For example, consider the buffer containing the following TLVs:
+ * <T:5><L:1><V> <T:6>...
+ * The TLV length clearly indicates that one byte is expected in V, but
+ * if the V processor returns with "want more data" even if the buffer
+ * contains way more data than the V processor have seen.
+ */
+#define SIZE_VIOLATION (ctx->left >= 0 && (size_t)ctx->left <= size)
+
+/*
+ * This macro "eats" the part of the buffer which is definitely "consumed",
+ * i.e. was correctly converted into local representation or rightfully skipped.
+ */
+#undef ADVANCE
+#define ADVANCE(num_bytes) do { \
+ size_t num = num_bytes; \
+ ptr = ((const char *)ptr) + num;\
+ size -= num; \
+ if(ctx->left >= 0) \
+ ctx->left -= num; \
+ consumed_myself += num; \
+ } while(0)
+
+/*
+ * Switch to the next phase of parsing.
+ */
+#undef NEXT_PHASE
+#undef PHASE_OUT
+#define NEXT_PHASE(ctx) do { \
+ ctx->phase++; \
+ ctx->step = 0; \
+ } while(0)
+#define PHASE_OUT(ctx) do { ctx->phase = 10; } while(0)
+
+/*
+ * Return a standardized complex structure.
+ */
+#undef RETURN
+#define RETURN(_code) do { \
+ rval.code = _code; \
+ rval.consumed = consumed_myself;\
+ return rval; \
+ } while(0)
+
+/*
+ * Check whether we are inside the extensions group.
+ */
+#define IN_EXTENSION_GROUP(specs, memb_idx) \
+ ( ((memb_idx) > (specs)->ext_after) \
+ &&((memb_idx) < (specs)->ext_before))
+
+
+/*
+ * Tags are canonically sorted in the tag2element map.
+ */
+static int
+_t2e_cmp(const void *ap, const void *bp) {
+ const asn_TYPE_tag2member_t *a = (const asn_TYPE_tag2member_t *)ap;
+ const asn_TYPE_tag2member_t *b = (const asn_TYPE_tag2member_t *)bp;
+
+ int a_class = BER_TAG_CLASS(a->el_tag);
+ int b_class = BER_TAG_CLASS(b->el_tag);
+
+ if(a_class == b_class) {
+ ber_tlv_tag_t a_value = BER_TAG_VALUE(a->el_tag);
+ ber_tlv_tag_t b_value = BER_TAG_VALUE(b->el_tag);
+
+ if(a_value == b_value) {
+ if(a->el_no > b->el_no)
+ return 1;
+ /*
+ * Important: we do not check
+ * for a->el_no <= b->el_no!
+ */
+ return 0;
+ } else if(a_value < b_value)
+ return -1;
+ else
+ return 1;
+ } else if(a_class < b_class) {
+ return -1;
+ } else {
+ return 1;
+ }
+}
+
+
+/*
+ * The decoder of the SEQUENCE type.
+ */
+asn_dec_rval_t
+SEQUENCE_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ void **struct_ptr, const void *ptr, size_t size, int tag_mode) {
+ /*
+ * Bring closer parts of structure description.
+ */
+ asn_SEQUENCE_specifics_t *specs = (asn_SEQUENCE_specifics_t *)td->specifics;
+ asn_TYPE_member_t *elements = td->elements;
+
+ /*
+ * Parts of the structure being constructed.
+ */
+ void *st = *struct_ptr; /* Target structure. */
+ asn_struct_ctx_t *ctx; /* Decoder context */
+
+ ber_tlv_tag_t tlv_tag; /* T from TLV */
+ asn_dec_rval_t rval; /* Return code from subparsers */
+
+ ssize_t consumed_myself = 0; /* Consumed bytes from ptr */
+ int edx; /* SEQUENCE element's index */
+
+ ASN_DEBUG("Decoding %s as SEQUENCE", td->name);
+
+ /*
+ * Create the target structure if it is not present already.
+ */
+ if(st == 0) {
+ st = *struct_ptr = CALLOC(1, specs->struct_size);
+ if(st == 0) {
+ RETURN(RC_FAIL);
+ }
+ }
+
+ /*
+ * Restore parsing context.
+ */
+ ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset);
+
+ /*
+ * Start to parse where left previously
+ */
+ switch(ctx->phase) {
+ case 0:
+ /*
+ * PHASE 0.
+ * Check that the set of tags associated with given structure
+ * perfectly fits our expectations.
+ */
+
+ rval = ber_check_tags(opt_codec_ctx, td, ctx, ptr, size,
+ tag_mode, 1, &ctx->left, 0);
+ if(rval.code != RC_OK) {
+ ASN_DEBUG("%s tagging check failed: %d",
+ td->name, rval.code);
+ return rval;
+ }
+
+ if(ctx->left >= 0)
+ ctx->left += rval.consumed; /* ?Substracted below! */
+ ADVANCE(rval.consumed);
+
+ NEXT_PHASE(ctx);
+
+ ASN_DEBUG("Structure consumes %ld bytes, buffer %ld",
+ (long)ctx->left, (long)size);
+
+ /* Fall through */
+ case 1:
+ /*
+ * PHASE 1.
+ * From the place where we've left it previously,
+ * try to decode the next member from the list of
+ * this structure's elements.
+ * (ctx->step) stores the member being processed
+ * between invocations and the microphase {0,1} of parsing
+ * that member:
+ * step = (<member_number> * 2 + <microphase>).
+ */
+ for(edx = (ctx->step >> 1); edx < td->elements_count;
+ edx++, ctx->step = (ctx->step & ~1) + 2) {
+ void *memb_ptr; /* Pointer to the member */
+ void **memb_ptr2; /* Pointer to that pointer */
+ ssize_t tag_len; /* Length of TLV's T */
+ int opt_edx_end; /* Next non-optional element */
+ int use_bsearch;
+ int n;
+
+ if(ctx->step & 1)
+ goto microphase2;
+
+ /*
+ * MICROPHASE 1: Synchronize decoding.
+ */
+ ASN_DEBUG("In %s SEQUENCE left %d, edx=%d flags=%d"
+ " opt=%d ec=%d",
+ td->name, (int)ctx->left, edx,
+ elements[edx].flags, elements[edx].optional,
+ td->elements_count);
+
+ if(ctx->left == 0 /* No more stuff is expected */
+ && (
+ /* Explicit OPTIONAL specification reaches the end */
+ (edx + elements[edx].optional
+ == td->elements_count)
+ ||
+ /* All extensions are optional */
+ (IN_EXTENSION_GROUP(specs, edx)
+ && specs->ext_before > td->elements_count)
+ )
+ ) {
+ ASN_DEBUG("End of SEQUENCE %s", td->name);
+ /*
+ * Found the legitimate end of the structure.
+ */
+ PHASE_OUT(ctx);
+ RETURN(RC_OK);
+ }
+
+ /*
+ * Fetch the T from TLV.
+ */
+ tag_len = ber_fetch_tag(ptr, LEFT, &tlv_tag);
+ ASN_DEBUG("Current tag in %s SEQUENCE for element %d "
+ "(%s) is %s encoded in %d bytes, of frame %ld",
+ td->name, edx, elements[edx].name,
+ ber_tlv_tag_string(tlv_tag), (int)tag_len, (long)LEFT);
+ switch(tag_len) {
+ case 0: if(!SIZE_VIOLATION) RETURN(RC_WMORE);
+ /* Fall through */
+ case -1: RETURN(RC_FAIL);
+ }
+
+ if(ctx->left < 0 && ((const uint8_t *)ptr)[0] == 0) {
+ if(LEFT < 2) {
+ if(SIZE_VIOLATION)
+ RETURN(RC_FAIL);
+ else
+ RETURN(RC_WMORE);
+ } else if(((const uint8_t *)ptr)[1] == 0) {
+ ASN_DEBUG("edx = %d, opt = %d, ec=%d",
+ edx, elements[edx].optional,
+ td->elements_count);
+ if((edx + elements[edx].optional
+ == td->elements_count)
+ || (IN_EXTENSION_GROUP(specs, edx)
+ && specs->ext_before
+ > td->elements_count)) {
+ /*
+ * Yeah, baby! Found the terminator
+ * of the indefinite length structure.
+ */
+ /*
+ * Proceed to the canonical
+ * finalization function.
+ * No advancing is necessary.
+ */
+ goto phase3;
+ }
+ }
+ }
+
+ /*
+ * Find the next available type with this tag.
+ */
+ use_bsearch = 0;
+ opt_edx_end = edx + elements[edx].optional + 1;
+ if(opt_edx_end > td->elements_count)
+ opt_edx_end = td->elements_count; /* Cap */
+ else if(opt_edx_end - edx > 8) {
+ /* Limit the scope of linear search... */
+ opt_edx_end = edx + 8;
+ use_bsearch = 1;
+ /* ... and resort to bsearch() */
+ }
+ for(n = edx; n < opt_edx_end; n++) {
+ if(BER_TAGS_EQUAL(tlv_tag, elements[n].tag)) {
+ /*
+ * Found element corresponding to the tag
+ * being looked at.
+ * Reposition over the right element.
+ */
+ edx = n;
+ ctx->step = 1 + 2 * edx; /* Remember! */
+ goto microphase2;
+ } else if(elements[n].flags & ATF_OPEN_TYPE) {
+ /*
+ * This is the ANY type, which may bear
+ * any flag whatsoever.
+ */
+ edx = n;
+ ctx->step = 1 + 2 * edx; /* Remember! */
+ goto microphase2;
+ } else if(elements[n].tag == (ber_tlv_tag_t)-1) {
+ use_bsearch = 1;
+ break;
+ }
+ }
+ if(use_bsearch) {
+ /*
+ * Resort to a binary search over
+ * sorted array of tags.
+ */
+ asn_TYPE_tag2member_t *t2m;
+ asn_TYPE_tag2member_t key;
+ key.el_tag = tlv_tag;
+ key.el_no = edx;
+ t2m = (asn_TYPE_tag2member_t *)bsearch(&key,
+ specs->tag2el, specs->tag2el_count,
+ sizeof(specs->tag2el[0]), _t2e_cmp);
+ if(t2m) {
+ asn_TYPE_tag2member_t *best = 0;
+ asn_TYPE_tag2member_t *t2m_f, *t2m_l;
+ int edx_max = edx + elements[edx].optional;
+ /*
+ * Rewind to the first element with that tag,
+ * `cause bsearch() does not guarantee order.
+ */
+ t2m_f = t2m + t2m->toff_first;
+ t2m_l = t2m + t2m->toff_last;
+ for(t2m = t2m_f; t2m <= t2m_l; t2m++) {
+ if(t2m->el_no > edx_max) break;
+ if(t2m->el_no < edx) continue;
+ best = t2m;
+ }
+ if(best) {
+ edx = best->el_no;
+ ctx->step = 1 + 2 * edx;
+ goto microphase2;
+ }
+ }
+ n = opt_edx_end;
+ }
+ if(n == opt_edx_end) {
+ /*
+ * If tag is unknown, it may be either
+ * an unknown (thus, incorrect) tag,
+ * or an extension (...),
+ * or an end of the indefinite-length structure.
+ */
+ if(!IN_EXTENSION_GROUP(specs, edx)) {
+ ASN_DEBUG("Unexpected tag %s (at %d)",
+ ber_tlv_tag_string(tlv_tag), edx);
+ ASN_DEBUG("Expected tag %s (%s)%s",
+ ber_tlv_tag_string(elements[edx].tag),
+ elements[edx].name,
+ elements[edx].optional
+ ?" or alternatives":"");
+ RETURN(RC_FAIL);
+ } else {
+ /* Skip this tag */
+ ssize_t skip;
+
+ skip = ber_skip_length(opt_codec_ctx,
+ BER_TLV_CONSTRUCTED(ptr),
+ (const char *)ptr + tag_len,
+ LEFT - tag_len);
+ ASN_DEBUG("Skip length %d in %s",
+ (int)skip, td->name);
+ switch(skip) {
+ case 0: if(!SIZE_VIOLATION) RETURN(RC_WMORE);
+ /* Fall through */
+ case -1: RETURN(RC_FAIL);
+ }
+
+ ADVANCE(skip + tag_len);
+ ctx->step -= 2;
+ edx--;
+ continue; /* Try again with the next tag */
+ }
+ }
+
+ /*
+ * MICROPHASE 2: Invoke the member-specific decoder.
+ */
+ ctx->step |= 1; /* Confirm entering next microphase */
+ microphase2:
+ ASN_DEBUG("Inside SEQUENCE %s MF2", td->name);
+
+ /*
+ * Compute the position of the member inside a structure,
+ * and also a type of containment (it may be contained
+ * as pointer or using inline inclusion).
+ */
+ if(elements[edx].flags & ATF_POINTER) {
+ /* Member is a pointer to another structure */
+ memb_ptr2 = (void **)((char *)st + elements[edx].memb_offset);
+ } else {
+ /*
+ * A pointer to a pointer
+ * holding the start of the structure
+ */
+ memb_ptr = (char *)st + elements[edx].memb_offset;
+ memb_ptr2 = &memb_ptr;
+ }
+ /*
+ * Invoke the member fetch routine according to member's type
+ */
+ rval = elements[edx].type->ber_decoder(opt_codec_ctx,
+ elements[edx].type,
+ memb_ptr2, ptr, LEFT,
+ elements[edx].tag_mode);
+ ASN_DEBUG("In %s SEQUENCE decoded %d %s of %d "
+ "in %d bytes rval.code %d, size=%d",
+ td->name, edx, elements[edx].type->name,
+ (int)LEFT, (int)rval.consumed, rval.code, (int)size);
+ switch(rval.code) {
+ case RC_OK:
+ break;
+ case RC_WMORE: /* More data expected */
+ if(!SIZE_VIOLATION) {
+ ADVANCE(rval.consumed);
+ RETURN(RC_WMORE);
+ }
+ ASN_DEBUG("Size violation (c->l=%ld <= s=%ld)",
+ (long)ctx->left, (long)size);
+ /* Fall through */
+ case RC_FAIL: /* Fatal error */
+ RETURN(RC_FAIL);
+ } /* switch(rval) */
+
+ ADVANCE(rval.consumed);
+ } /* for(all structure members) */
+
+ phase3:
+ ctx->phase = 3;
+ case 3: /* 00 and other tags expected */
+ case 4: /* only 00's expected */
+
+ ASN_DEBUG("SEQUENCE %s Leftover: %ld, size = %ld",
+ td->name, (long)ctx->left, (long)size);
+
+ /*
+ * Skip everything until the end of the SEQUENCE.
+ */
+ while(ctx->left) {
+ ssize_t tl, ll;
+
+ tl = ber_fetch_tag(ptr, LEFT, &tlv_tag);
+ switch(tl) {
+ case 0: if(!SIZE_VIOLATION) RETURN(RC_WMORE);
+ /* Fall through */
+ case -1: RETURN(RC_FAIL);
+ }
+
+ /*
+ * If expected <0><0>...
+ */
+ if(ctx->left < 0
+ && ((const uint8_t *)ptr)[0] == 0) {
+ if(LEFT < 2) {
+ if(SIZE_VIOLATION)
+ RETURN(RC_FAIL);
+ else
+ RETURN(RC_WMORE);
+ } else if(((const uint8_t *)ptr)[1] == 0) {
+ /*
+ * Correctly finished with <0><0>.
+ */
+ ADVANCE(2);
+ ctx->left++;
+ ctx->phase = 4;
+ continue;
+ }
+ }
+
+ if(!IN_EXTENSION_GROUP(specs, td->elements_count)
+ || ctx->phase == 4) {
+ ASN_DEBUG("Unexpected continuation "
+ "of a non-extensible type "
+ "%s (SEQUENCE): %s",
+ td->name,
+ ber_tlv_tag_string(tlv_tag));
+ RETURN(RC_FAIL);
+ }
+
+ ll = ber_skip_length(opt_codec_ctx,
+ BER_TLV_CONSTRUCTED(ptr),
+ (const char *)ptr + tl, LEFT - tl);
+ switch(ll) {
+ case 0: if(!SIZE_VIOLATION) RETURN(RC_WMORE);
+ /* Fall through */
+ case -1: RETURN(RC_FAIL);
+ }
+
+ ADVANCE(tl + ll);
+ }
+
+ PHASE_OUT(ctx);
+ }
+
+ RETURN(RC_OK);
+}
+
+
+/*
+ * The DER encoder of the SEQUENCE type.
+ */
+asn_enc_rval_t
+SEQUENCE_encode_der(asn_TYPE_descriptor_t *td,
+ void *sptr, int tag_mode, ber_tlv_tag_t tag,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ size_t computed_size = 0;
+ asn_enc_rval_t erval;
+ ssize_t ret;
+ int edx;
+
+ ASN_DEBUG("%s %s as SEQUENCE",
+ cb?"Encoding":"Estimating", td->name);
+
+ /*
+ * Gather the length of the underlying members sequence.
+ */
+ for(edx = 0; edx < td->elements_count; edx++) {
+ asn_TYPE_member_t *elm = &td->elements[edx];
+ void *memb_ptr;
+ if(elm->flags & ATF_POINTER) {
+ memb_ptr = *(void **)((char *)sptr + elm->memb_offset);
+ if(!memb_ptr) {
+ if(elm->optional) continue;
+ /* Mandatory element is missing */
+ _ASN_ENCODE_FAILED;
+ }
+ } else {
+ memb_ptr = (void *)((char *)sptr + elm->memb_offset);
+ }
+ erval = elm->type->der_encoder(elm->type, memb_ptr,
+ elm->tag_mode, elm->tag,
+ 0, 0);
+ if(erval.encoded == -1)
+ return erval;
+ computed_size += erval.encoded;
+ ASN_DEBUG("Member %d %s estimated %ld bytes",
+ edx, elm->name, (long)erval.encoded);
+ }
+
+ /*
+ * Encode the TLV for the sequence itself.
+ */
+ ret = der_write_tags(td, computed_size, tag_mode, 1, tag, cb, app_key);
+ ASN_DEBUG("Wrote tags: %ld (+%ld)", (long)ret, (long)computed_size);
+ if(ret == -1)
+ _ASN_ENCODE_FAILED;
+ erval.encoded = computed_size + ret;
+
+ if(!cb) _ASN_ENCODED_OK(erval);
+
+ /*
+ * Encode all members.
+ */
+ for(edx = 0; edx < td->elements_count; edx++) {
+ asn_TYPE_member_t *elm = &td->elements[edx];
+ asn_enc_rval_t tmperval;
+ void *memb_ptr;
+
+ if(elm->flags & ATF_POINTER) {
+ memb_ptr = *(void **)((char *)sptr + elm->memb_offset);
+ if(!memb_ptr) continue;
+ } else {
+ memb_ptr = (void *)((char *)sptr + elm->memb_offset);
+ }
+ tmperval = elm->type->der_encoder(elm->type, memb_ptr,
+ elm->tag_mode, elm->tag,
+ cb, app_key);
+ if(tmperval.encoded == -1)
+ return tmperval;
+ computed_size -= tmperval.encoded;
+ ASN_DEBUG("Member %d %s of SEQUENCE %s encoded in %ld bytes",
+ edx, elm->name, td->name, (long)tmperval.encoded);
+ }
+
+ if(computed_size != 0)
+ /*
+ * Encoded size is not equal to the computed size.
+ */
+ _ASN_ENCODE_FAILED;
+
+ _ASN_ENCODED_OK(erval);
+}
+
+
+#undef XER_ADVANCE
+#define XER_ADVANCE(num_bytes) do { \
+ size_t num = num_bytes; \
+ buf_ptr = ((const char *)buf_ptr) + num;\
+ size -= num; \
+ consumed_myself += num; \
+ } while(0)
+
+/*
+ * Decode the XER (XML) data.
+ */
+asn_dec_rval_t
+SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ void **struct_ptr, const char *opt_mname,
+ const void *buf_ptr, size_t size) {
+ /*
+ * Bring closer parts of structure description.
+ */
+ asn_SEQUENCE_specifics_t *specs
+ = (asn_SEQUENCE_specifics_t *)td->specifics;
+ asn_TYPE_member_t *elements = td->elements;
+ const char *xml_tag = opt_mname ? opt_mname : td->xml_tag;
+
+ /*
+ * ... and parts of the structure being constructed.
+ */
+ void *st = *struct_ptr; /* Target structure. */
+ asn_struct_ctx_t *ctx; /* Decoder context */
+
+ asn_dec_rval_t rval; /* Return value from a decoder */
+ ssize_t consumed_myself = 0; /* Consumed bytes from ptr */
+ int edx; /* Element index */
+ int edx_end;
+
+ /*
+ * Create the target structure if it is not present already.
+ */
+ if(st == 0) {
+ st = *struct_ptr = CALLOC(1, specs->struct_size);
+ if(st == 0) RETURN(RC_FAIL);
+ }
+
+ /*
+ * Restore parsing context.
+ */
+ ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset);
+
+
+ /*
+ * Phases of XER/XML processing:
+ * Phase 0: Check that the opening tag matches our expectations.
+ * Phase 1: Processing body and reacting on closing tag.
+ * Phase 2: Processing inner type.
+ * Phase 3: Skipping unknown extensions.
+ * Phase 4: PHASED OUT
+ */
+ for(edx = ctx->step; ctx->phase <= 3;) {
+ pxer_chunk_type_e ch_type; /* XER chunk type */
+ ssize_t ch_size; /* Chunk size */
+ xer_check_tag_e tcv; /* Tag check value */
+ asn_TYPE_member_t *elm;
+ int n;
+
+ /*
+ * Go inside the inner member of a sequence.
+ */
+ if(ctx->phase == 2) {
+ asn_dec_rval_t tmprval;
+ void *memb_ptr; /* Pointer to the member */
+ void **memb_ptr2; /* Pointer to that pointer */
+
+ elm = &td->elements[edx];
+
+ if(elm->flags & ATF_POINTER) {
+ /* Member is a pointer to another structure */
+ memb_ptr2 = (void **)((char *)st
+ + elm->memb_offset);
+ } else {
+ memb_ptr = (char *)st + elm->memb_offset;
+ memb_ptr2 = &memb_ptr;
+ }
+
+ /* Invoke the inner type decoder, m.b. multiple times */
+ tmprval = elm->type->xer_decoder(opt_codec_ctx,
+ elm->type, memb_ptr2, elm->name,
+ buf_ptr, size);
+ XER_ADVANCE(tmprval.consumed);
+ if(tmprval.code != RC_OK)
+ RETURN(tmprval.code);
+ ctx->phase = 1; /* Back to body processing */
+ ctx->step = ++edx;
+ ASN_DEBUG("XER/SEQUENCE phase => %d, step => %d",
+ ctx->phase, ctx->step);
+ /* Fall through */
+ }
+
+ /*
+ * Get the next part of the XML stream.
+ */
+ ch_size = xer_next_token(&ctx->context, buf_ptr, size,
+ &ch_type);
+ switch(ch_size) {
+ case -1: RETURN(RC_FAIL);
+ case 0: RETURN(RC_WMORE);
+ default:
+ switch(ch_type) {
+ case PXER_COMMENT: /* Got XML comment */
+ case PXER_TEXT: /* Ignore free-standing text */
+ XER_ADVANCE(ch_size); /* Skip silently */
+ continue;
+ case PXER_TAG:
+ break; /* Check the rest down there */
+ }
+ }
+
+ tcv = xer_check_tag(buf_ptr, ch_size, xml_tag);
+ ASN_DEBUG("XER/SEQUENCE: tcv = %d, ph=%d [%s]",
+ tcv, ctx->phase, xml_tag);
+
+ /* Skip the extensions section */
+ if(ctx->phase == 3) {
+ switch(xer_skip_unknown(tcv, &ctx->left)) {
+ case -1:
+ ctx->phase = 4;
+ RETURN(RC_FAIL);
+ case 0:
+ XER_ADVANCE(ch_size);
+ continue;
+ case 1:
+ XER_ADVANCE(ch_size);
+ ctx->phase = 1;
+ continue;
+ case 2:
+ ctx->phase = 1;
+ break;
+ }
+ }
+
+ switch(tcv) {
+ case XCT_CLOSING:
+ if(ctx->phase == 0) break;
+ ctx->phase = 0;
+ /* Fall through */
+ case XCT_BOTH:
+ if(ctx->phase == 0) {
+ if(edx >= td->elements_count
+ ||
+ /* Explicit OPTIONAL specs reaches the end */
+ (edx + elements[edx].optional
+ == td->elements_count)
+ ||
+ /* All extensions are optional */
+ (IN_EXTENSION_GROUP(specs, edx)
+ && specs->ext_before
+ > td->elements_count)
+ ) {
+ XER_ADVANCE(ch_size);
+ ctx->phase = 4; /* Phase out */
+ RETURN(RC_OK);
+ } else {
+ ASN_DEBUG("Premature end of XER SEQUENCE");
+ RETURN(RC_FAIL);
+ }
+ }
+ /* Fall through */
+ case XCT_OPENING:
+ if(ctx->phase == 0) {
+ XER_ADVANCE(ch_size);
+ ctx->phase = 1; /* Processing body phase */
+ continue;
+ }
+ /* Fall through */
+ case XCT_UNKNOWN_OP:
+ case XCT_UNKNOWN_BO:
+
+ ASN_DEBUG("XER/SEQUENCE: tcv=%d, ph=%d, edx=%d",
+ tcv, ctx->phase, edx);
+ if(ctx->phase != 1) {
+ break; /* Really unexpected */
+ }
+
+ if(edx < td->elements_count) {
+ /*
+ * Search which member corresponds to this tag.
+ */
+ edx_end = edx + elements[edx].optional + 1;
+ if(edx_end > td->elements_count)
+ edx_end = td->elements_count;
+ for(n = edx; n < edx_end; n++) {
+ elm = &td->elements[n];
+ tcv = xer_check_tag(buf_ptr,
+ ch_size, elm->name);
+ switch(tcv) {
+ case XCT_BOTH:
+ case XCT_OPENING:
+ /*
+ * Process this member.
+ */
+ ctx->step = edx = n;
+ ctx->phase = 2;
+ break;
+ case XCT_UNKNOWN_OP:
+ case XCT_UNKNOWN_BO:
+ continue;
+ default:
+ n = edx_end;
+ break; /* Phase out */
+ }
+ break;
+ }
+ if(n != edx_end)
+ continue;
+ } else {
+ ASN_DEBUG("Out of defined members: %d/%d",
+ edx, td->elements_count);
+ }
+
+ /* It is expected extension */
+ if(IN_EXTENSION_GROUP(specs,
+ edx + (edx < td->elements_count
+ ? elements[edx].optional : 0))) {
+ ASN_DEBUG("Got anticipated extension at %d",
+ edx);
+ /*
+ * Check for (XCT_BOTH or XCT_UNKNOWN_BO)
+ * By using a mask. Only record a pure
+ * <opening> tags.
+ */
+ if(tcv & XCT_CLOSING) {
+ /* Found </extension> without body */
+ } else {
+ ctx->left = 1;
+ ctx->phase = 3; /* Skip ...'s */
+ }
+ XER_ADVANCE(ch_size);
+ continue;
+ }
+
+ /* Fall through */
+ default:
+ break;
+ }
+
+ ASN_DEBUG("Unexpected XML tag in SEQUENCE [%c%c%c%c%c%c]",
+ size>0?((const char *)buf_ptr)[0]:'.',
+ size>1?((const char *)buf_ptr)[1]:'.',
+ size>2?((const char *)buf_ptr)[2]:'.',
+ size>3?((const char *)buf_ptr)[3]:'.',
+ size>4?((const char *)buf_ptr)[4]:'.',
+ size>5?((const char *)buf_ptr)[5]:'.');
+ break;
+ }
+
+ ctx->phase = 4; /* "Phase out" on hard failure */
+ RETURN(RC_FAIL);
+}
+
+asn_enc_rval_t
+SEQUENCE_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ asn_enc_rval_t er;
+ int xcan = (flags & XER_F_CANONICAL);
+ int edx;
+
+ if(!sptr)
+ _ASN_ENCODE_FAILED;
+
+ er.encoded = 0;
+
+ for(edx = 0; edx < td->elements_count; edx++) {
+ asn_enc_rval_t tmper;
+ asn_TYPE_member_t *elm = &td->elements[edx];
+ void *memb_ptr;
+ const char *mname = elm->name;
+ unsigned int mlen = strlen(mname);
+
+ if(elm->flags & ATF_POINTER) {
+ memb_ptr = *(void **)((char *)sptr + elm->memb_offset);
+ if(!memb_ptr) {
+ if(elm->optional)
+ continue;
+ /* Mandatory element is missing */
+ _ASN_ENCODE_FAILED;
+ }
+ } else {
+ memb_ptr = (void *)((char *)sptr + elm->memb_offset);
+ }
+
+ if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel);
+ _ASN_CALLBACK3("<", 1, mname, mlen, ">", 1);
+
+ /* Print the member itself */
+ tmper = elm->type->xer_encoder(elm->type, memb_ptr,
+ ilevel + 1, flags, cb, app_key);
+ if(tmper.encoded == -1) return tmper;
+
+ _ASN_CALLBACK3("</", 2, mname, mlen, ">", 1);
+ er.encoded += 5 + (2 * mlen) + tmper.encoded;
+ }
+
+ if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel - 1);
+
+ _ASN_ENCODED_OK(er);
+cb_failed:
+ _ASN_ENCODE_FAILED;
+}
+
+int
+SEQUENCE_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ int edx;
+ int ret;
+
+ if(!sptr) return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
+
+ /* Dump preamble */
+ if(cb(td->name, strlen(td->name), app_key) < 0
+ || cb(" ::= {", 6, app_key) < 0)
+ return -1;
+
+ for(edx = 0; edx < td->elements_count; edx++) {
+ asn_TYPE_member_t *elm = &td->elements[edx];
+ const void *memb_ptr;
+
+ if(elm->flags & ATF_POINTER) {
+ memb_ptr = *(const void * const *)((const char *)sptr + elm->memb_offset);
+ if(!memb_ptr) {
+ if(elm->optional) continue;
+ /* Print <absent> line */
+ /* Fall through */
+ }
+ } else {
+ memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
+ }
+
+ /* Indentation */
+ _i_INDENT(1);
+
+ /* Print the member's name and stuff */
+ if(cb(elm->name, strlen(elm->name), app_key) < 0
+ || cb(": ", 2, app_key) < 0)
+ return -1;
+
+ /* Print the member itself */
+ ret = elm->type->print_struct(elm->type, memb_ptr, ilevel + 1,
+ cb, app_key);
+ if(ret) return ret;
+ }
+
+ ilevel--;
+ _i_INDENT(1);
+
+ return (cb("}", 1, app_key) < 0) ? -1 : 0;
+}
+
+void
+SEQUENCE_free(asn_TYPE_descriptor_t *td, void *sptr, int contents_only) {
+ int edx;
+
+ if(!td || !sptr)
+ return;
+
+ ASN_DEBUG("Freeing %s as SEQUENCE", td->name);
+
+ for(edx = 0; edx < td->elements_count; edx++) {
+ asn_TYPE_member_t *elm = &td->elements[edx];
+ void *memb_ptr;
+ if(elm->flags & ATF_POINTER) {
+ memb_ptr = *(void **)((char *)sptr + elm->memb_offset);
+ if(memb_ptr)
+ ASN_STRUCT_FREE(*elm->type, memb_ptr);
+ } else {
+ memb_ptr = (void *)((char *)sptr + elm->memb_offset);
+ ASN_STRUCT_FREE_CONTENTS_ONLY(*elm->type, memb_ptr);
+ }
+ }
+
+ if(!contents_only) {
+ FREEMEM(sptr);
+ }
+}
+
+int
+SEQUENCE_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
+ asn_app_constraint_failed_f *ctfailcb, void *app_key) {
+ int edx;
+
+ if(!sptr) {
+ _ASN_CTFAIL(app_key, td,
+ "%s: value not given (%s:%d)",
+ td->name, __FILE__, __LINE__);
+ return -1;
+ }
+
+ /*
+ * Iterate over structure members and check their validity.
+ */
+ for(edx = 0; edx < td->elements_count; edx++) {
+ asn_TYPE_member_t *elm = &td->elements[edx];
+ const void *memb_ptr;
+
+ if(elm->flags & ATF_POINTER) {
+ memb_ptr = *(const void * const *)((const char *)sptr + elm->memb_offset);
+ if(!memb_ptr) {
+ if(elm->optional)
+ continue;
+ _ASN_CTFAIL(app_key, td,
+ "%s: mandatory element %s absent (%s:%d)",
+ td->name, elm->name, __FILE__, __LINE__);
+ return -1;
+ }
+ } else {
+ memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
+ }
+
+ if(elm->memb_constraints) {
+ int ret = elm->memb_constraints(elm->type, memb_ptr,
+ ctfailcb, app_key);
+ if(ret) return ret;
+ } else {
+ int ret = elm->type->check_constraints(elm->type,
+ memb_ptr, ctfailcb, app_key);
+ if(ret) return ret;
+ /*
+ * Cannot inherit it earlier:
+ * need to make sure we get the updated version.
+ */
+ elm->memb_constraints = elm->type->check_constraints;
+ }
+ }
+
+ return 0;
+}
+
+asn_dec_rval_t
+SEQUENCE_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
+ asn_SEQUENCE_specifics_t *specs = (asn_SEQUENCE_specifics_t *)td->specifics;
+ void *st = *sptr; /* Target structure. */
+ int extpresent = 0; /* Extension additions are present */
+ uint8_t *opres; /* Presence of optional root members */
+ asn_per_data_t opmd;
+ asn_dec_rval_t rv;
+ int edx;
+
+ (void)constraints;
+
+ if(_ASN_STACK_OVERFLOW_CHECK(opt_codec_ctx))
+ _ASN_DECODE_FAILED;
+
+ if(!st) {
+ st = *sptr = CALLOC(1, specs->struct_size);
+ if(!st) _ASN_DECODE_FAILED;
+ }
+
+ ASN_DEBUG("Decoding %s as SEQUENCE (UPER)", td->name);
+
+ /* Handle extensions */
+ if(specs->ext_before >= 0) {
+ extpresent = per_get_few_bits(pd, 1);
+ if(extpresent < 0) _ASN_DECODE_STARVED;
+ }
+
+ /* Prepare a place and read-in the presence bitmap */
+ if(specs->roms_count) {
+ opres = (uint8_t *)MALLOC(((specs->roms_count + 7) >> 3) + 1);
+ if(!opres) _ASN_DECODE_FAILED;
+ /* Get the presence map */
+ if(per_get_many_bits(pd, opres, 0, specs->roms_count)) {
+ FREEMEM(opres);
+ _ASN_DECODE_STARVED;
+ }
+ opmd.buffer = opres;
+ opmd.nboff = 0;
+ opmd.nbits = specs->roms_count;
+ ASN_DEBUG("Read in presence bitmap for %s of %d bits (%x..)",
+ td->name, specs->roms_count, *opres);
+ } else {
+ opres = 0;
+ memset(&opmd, 0, sizeof opmd);
+ }
+
+ /*
+ * Get the sequence ROOT elements.
+ */
+ for(edx = 0; edx < ((specs->ext_before < 0)
+ ? td->elements_count : specs->ext_before + 1); edx++) {
+ asn_TYPE_member_t *elm = &td->elements[edx];
+ void *memb_ptr; /* Pointer to the member */
+ void **memb_ptr2; /* Pointer to that pointer */
+
+ /* Fetch the pointer to this member */
+ if(elm->flags & ATF_POINTER) {
+ memb_ptr2 = (void **)((char *)st + elm->memb_offset);
+ } else {
+ memb_ptr = (char *)st + elm->memb_offset;
+ memb_ptr2 = &memb_ptr;
+ }
+
+ /* Deal with optionality */
+ if(elm->optional) {
+ int present = per_get_few_bits(&opmd, 1);
+ ASN_DEBUG("Member %s->%s is optional, p=%d (%d->%d)",
+ td->name, elm->name, present,
+ (int)opmd.nboff, (int)opmd.nbits);
+ if(present == 0) {
+ /* This element is not present */
+ if(elm->default_value) {
+ /* Fill-in DEFAULT */
+ if(elm->default_value(1, memb_ptr2)) {
+ FREEMEM(opres);
+ _ASN_DECODE_FAILED;
+ }
+ }
+ /* The member is just not present */
+ continue;
+ }
+ /* Fall through */
+ }
+
+ /* Fetch the member from the stream */
+ ASN_DEBUG("Decoding member %s in %s", elm->name, td->name);
+ rv = elm->type->uper_decoder(opt_codec_ctx, elm->type,
+ elm->per_constraints, memb_ptr2, pd);
+ if(rv.code != RC_OK) {
+ ASN_DEBUG("Failed decode %s in %s",
+ elm->name, td->name);
+ FREEMEM(opres);
+ return rv;
+ }
+ }
+
+ /*
+ * Deal with extensions.
+ */
+ if(extpresent) {
+ ASN_DEBUG("Extensibility for %s: NOT IMPLEMENTED", td->name);
+ _ASN_DECODE_FAILED;
+ } else {
+ for(edx = specs->roms_count; edx < specs->roms_count
+ + specs->aoms_count; edx++) {
+ asn_TYPE_member_t *elm = &td->elements[edx];
+ void *memb_ptr; /* Pointer to the member */
+ void **memb_ptr2; /* Pointer to that pointer */
+
+ if(!elm->default_value) continue;
+
+ /* Fetch the pointer to this member */
+ if(elm->flags & ATF_POINTER) {
+ memb_ptr2 = (void **)((char *)st
+ + elm->memb_offset);
+ } else {
+ memb_ptr = (char *)st + elm->memb_offset;
+ memb_ptr2 = &memb_ptr;
+ }
+
+ /* Set default value */
+ if(elm->default_value(1, memb_ptr2)) {
+ FREEMEM(opres);
+ _ASN_DECODE_FAILED;
+ }
+ }
+ }
+
+ rv.consumed = 0;
+ rv.code = RC_OK;
+ FREEMEM(opres);
+ return rv;
+}
+
+asn_enc_rval_t
+SEQUENCE_encode_uper(asn_TYPE_descriptor_t *td,
+ asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
+ asn_SEQUENCE_specifics_t *specs
+ = (asn_SEQUENCE_specifics_t *)td->specifics;
+ asn_enc_rval_t er;
+ int edx;
+ int i;
+
+ (void)constraints;
+
+ if(!sptr)
+ _ASN_ENCODE_FAILED;
+
+ er.encoded = 0;
+
+ ASN_DEBUG("Encoding %s as SEQUENCE (UPER)", td->name);
+ if(specs->ext_before >= 0)
+ _ASN_ENCODE_FAILED; /* We don't encode extensions yet */
+
+ /* Encode a presence bitmap */
+ for(i = 0; i < specs->roms_count; i++) {
+ asn_TYPE_member_t *elm;
+ void *memb_ptr; /* Pointer to the member */
+ void **memb_ptr2; /* Pointer to that pointer */
+ int present;
+
+ edx = specs->oms[i];
+ elm = &td->elements[edx];
+
+ /* Fetch the pointer to this member */
+ if(elm->flags & ATF_POINTER) {
+ memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
+ present = (*memb_ptr2 != 0);
+ } else {
+ memb_ptr = (void *)((char *)sptr + elm->memb_offset);
+ memb_ptr2 = &memb_ptr;
+ present = 1;
+ }
+
+ /* Eliminate default values */
+ if(present && elm->default_value
+ && elm->default_value(0, memb_ptr2) == 1)
+ present = 0;
+
+ ASN_DEBUG("Element %s %s %s->%s is %s",
+ elm->flags & ATF_POINTER ? "ptr" : "inline",
+ elm->default_value ? "def" : "wtv",
+ td->name, elm->name, present ? "present" : "absent");
+ if(per_put_few_bits(po, present, 1))
+ _ASN_ENCODE_FAILED;
+ }
+
+ /*
+ * Get the sequence ROOT elements.
+ */
+ for(edx = 0; edx < ((specs->ext_before < 0)
+ ? td->elements_count : specs->ext_before + 1); edx++) {
+ asn_TYPE_member_t *elm = &td->elements[edx];
+ void *memb_ptr; /* Pointer to the member */
+ void **memb_ptr2; /* Pointer to that pointer */
+
+ /* Fetch the pointer to this member */
+ if(elm->flags & ATF_POINTER) {
+ memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
+ if(!*memb_ptr2) {
+ ASN_DEBUG("Element %s %d not present",
+ elm->name, edx);
+ if(elm->optional)
+ continue;
+ /* Mandatory element is missing */
+ _ASN_ENCODE_FAILED;
+ }
+ } else {
+ memb_ptr = (void *)((char *)sptr + elm->memb_offset);
+ memb_ptr2 = &memb_ptr;
+ }
+
+ /* Eliminate default values */
+ if(elm->default_value && elm->default_value(0, memb_ptr2) == 1)
+ continue;
+
+ er = elm->type->uper_encoder(elm->type, elm->per_constraints,
+ *memb_ptr2, po);
+ if(er.encoded == -1)
+ return er;
+ }
+
+ _ASN_ENCODED_OK(er);
+}
+
--- /dev/null
+/*-
+ * Copyright (c) 2003, 2004, 2006 Lev Walkin <vlm@lionet.info>.
+ * All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#include <asn_internal.h>
+#include <constr_SEQUENCE_OF.h>
+#include <asn_SEQUENCE_OF.h>
+
+/*
+ * The DER encoder of the SEQUENCE OF type.
+ */
+asn_enc_rval_t
+SEQUENCE_OF_encode_der(asn_TYPE_descriptor_t *td, void *ptr,
+ int tag_mode, ber_tlv_tag_t tag,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ asn_TYPE_member_t *elm = td->elements;
+ asn_anonymous_sequence_ *list = _A_SEQUENCE_FROM_VOID(ptr);
+ size_t computed_size = 0;
+ ssize_t encoding_size = 0;
+ asn_enc_rval_t erval;
+ int edx;
+
+ ASN_DEBUG("Estimating size of SEQUENCE OF %s", td->name);
+
+ /*
+ * Gather the length of the underlying members sequence.
+ */
+ for(edx = 0; edx < list->count; edx++) {
+ void *memb_ptr = list->array[edx];
+ if(!memb_ptr) continue;
+ erval = elm->type->der_encoder(elm->type, memb_ptr,
+ 0, elm->tag,
+ 0, 0);
+ if(erval.encoded == -1)
+ return erval;
+ computed_size += erval.encoded;
+ }
+
+ /*
+ * Encode the TLV for the sequence itself.
+ */
+ encoding_size = der_write_tags(td, computed_size, tag_mode, 1, tag,
+ cb, app_key);
+ if(encoding_size == -1) {
+ erval.encoded = -1;
+ erval.failed_type = td;
+ erval.structure_ptr = ptr;
+ return erval;
+ }
+
+ computed_size += encoding_size;
+ if(!cb) {
+ erval.encoded = computed_size;
+ _ASN_ENCODED_OK(erval);
+ }
+
+ ASN_DEBUG("Encoding members of SEQUENCE OF %s", td->name);
+
+ /*
+ * Encode all members.
+ */
+ for(edx = 0; edx < list->count; edx++) {
+ void *memb_ptr = list->array[edx];
+ if(!memb_ptr) continue;
+ erval = elm->type->der_encoder(elm->type, memb_ptr,
+ 0, elm->tag,
+ cb, app_key);
+ if(erval.encoded == -1)
+ return erval;
+ encoding_size += erval.encoded;
+ }
+
+ if(computed_size != (size_t)encoding_size) {
+ /*
+ * Encoded size is not equal to the computed size.
+ */
+ erval.encoded = -1;
+ erval.failed_type = td;
+ erval.structure_ptr = ptr;
+ } else {
+ erval.encoded = computed_size;
+ erval.structure_ptr = 0;
+ erval.failed_type = 0;
+ }
+
+ return erval;
+}
+
+asn_enc_rval_t
+SEQUENCE_OF_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ asn_enc_rval_t er;
+ asn_SET_OF_specifics_t *specs = (asn_SET_OF_specifics_t *)td->specifics;
+ asn_TYPE_member_t *elm = td->elements;
+ asn_anonymous_sequence_ *list = _A_SEQUENCE_FROM_VOID(sptr);
+ const char *mname = specs->as_XMLValueList
+ ? 0 : ((*elm->name) ? elm->name : elm->type->xml_tag);
+ unsigned int mlen = mname ? strlen(mname) : 0;
+ int xcan = (flags & XER_F_CANONICAL);
+ int i;
+
+ if(!sptr) _ASN_ENCODE_FAILED;
+
+ er.encoded = 0;
+
+ for(i = 0; i < list->count; i++) {
+ asn_enc_rval_t tmper;
+ void *memb_ptr = list->array[i];
+ if(!memb_ptr) continue;
+
+ if(mname) {
+ if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel);
+ _ASN_CALLBACK3("<", 1, mname, mlen, ">", 1);
+ }
+
+ tmper = elm->type->xer_encoder(elm->type, memb_ptr,
+ ilevel + 1, flags, cb, app_key);
+ if(tmper.encoded == -1) return tmper;
+ if(tmper.encoded == 0 && specs->as_XMLValueList) {
+ const char *name = elm->type->xml_tag;
+ size_t len = strlen(name);
+ if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel + 1);
+ _ASN_CALLBACK3("<", 1, name, len, "/>", 2);
+ }
+
+ if(mname) {
+ _ASN_CALLBACK3("</", 2, mname, mlen, ">", 1);
+ er.encoded += 5;
+ }
+
+ er.encoded += (2 * mlen) + tmper.encoded;
+ }
+
+ if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel - 1);
+
+ _ASN_ENCODED_OK(er);
+cb_failed:
+ _ASN_ENCODE_FAILED;
+}
+
+asn_enc_rval_t
+SEQUENCE_OF_encode_uper(asn_TYPE_descriptor_t *td,
+ asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
+ asn_anonymous_sequence_ *list;
+ asn_per_constraint_t *ct;
+ asn_enc_rval_t er;
+ asn_TYPE_member_t *elm = td->elements;
+ int seq;
+
+ if(!sptr) _ASN_ENCODE_FAILED;
+ list = _A_SEQUENCE_FROM_VOID(sptr);
+
+ er.encoded = 0;
+
+ ASN_DEBUG("Encoding %s as SEQUENCE OF (%d)", td->name, list->count);
+
+ if(constraints) ct = &constraints->size;
+ else if(td->per_constraints) ct = &td->per_constraints->size;
+ else ct = 0;
+
+ /* If extensible constraint, check if size is in root */
+ if(ct) {
+ int not_in_root = (list->count < ct->lower_bound
+ || list->count > ct->upper_bound);
+ ASN_DEBUG("lb %ld ub %ld %s",
+ ct->lower_bound, ct->upper_bound,
+ ct->flags & APC_EXTENSIBLE ? "ext" : "fix");
+ if(ct->flags & APC_EXTENSIBLE) {
+ /* Declare whether size is in extension root */
+ if(per_put_few_bits(po, not_in_root, 1))
+ _ASN_ENCODE_FAILED;
+ if(not_in_root) ct = 0;
+ } else if(not_in_root && ct->effective_bits >= 0)
+ _ASN_ENCODE_FAILED;
+ }
+
+ if(ct && ct->effective_bits >= 0) {
+ /* X.691, #19.5: No length determinant */
+ if(per_put_few_bits(po, list->count - ct->lower_bound,
+ ct->effective_bits))
+ _ASN_ENCODE_FAILED;
+ }
+
+ for(seq = -1; seq < list->count;) {
+ ssize_t mayEncode;
+ if(seq < 0) seq = 0;
+ if(ct && ct->effective_bits >= 0) {
+ mayEncode = list->count;
+ } else {
+ mayEncode = uper_put_length(po, list->count - seq);
+ if(mayEncode < 0) _ASN_ENCODE_FAILED;
+ }
+
+ while(mayEncode--) {
+ void *memb_ptr = list->array[seq++];
+ if(!memb_ptr) _ASN_ENCODE_FAILED;
+ er = elm->type->uper_encoder(elm->type,
+ elm->per_constraints, memb_ptr, po);
+ if(er.encoded == -1)
+ _ASN_ENCODE_FAILED;
+ }
+ }
+
+ _ASN_ENCODED_OK(er);
+}
+
--- /dev/null
+/*-
+ * Copyright (c) 2003, 2004, 2005 Lev Walkin <vlm@lionet.info>.
+ * All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#include <asn_internal.h>
+#include <constr_SET_OF.h>
+#include <asn_SET_OF.h>
+
+/*
+ * Number of bytes left for this structure.
+ * (ctx->left) indicates the number of bytes _transferred_ for the structure.
+ * (size) contains the number of bytes in the buffer passed.
+ */
+#define LEFT ((size<(size_t)ctx->left)?size:(size_t)ctx->left)
+
+/*
+ * If the subprocessor function returns with an indication that it wants
+ * more data, it may well be a fatal decoding problem, because the
+ * size is constrained by the <TLV>'s L, even if the buffer size allows
+ * reading more data.
+ * For example, consider the buffer containing the following TLVs:
+ * <T:5><L:1><V> <T:6>...
+ * The TLV length clearly indicates that one byte is expected in V, but
+ * if the V processor returns with "want more data" even if the buffer
+ * contains way more data than the V processor have seen.
+ */
+#define SIZE_VIOLATION (ctx->left >= 0 && (size_t)ctx->left <= size)
+
+/*
+ * This macro "eats" the part of the buffer which is definitely "consumed",
+ * i.e. was correctly converted into local representation or rightfully skipped.
+ */
+#undef ADVANCE
+#define ADVANCE(num_bytes) do { \
+ size_t num = num_bytes; \
+ ptr = ((const char *)ptr) + num;\
+ size -= num; \
+ if(ctx->left >= 0) \
+ ctx->left -= num; \
+ consumed_myself += num; \
+ } while(0)
+
+/*
+ * Switch to the next phase of parsing.
+ */
+#undef NEXT_PHASE
+#undef PHASE_OUT
+#define NEXT_PHASE(ctx) do { \
+ ctx->phase++; \
+ ctx->step = 0; \
+ } while(0)
+#define PHASE_OUT(ctx) do { ctx->phase = 10; } while(0)
+
+/*
+ * Return a standardized complex structure.
+ */
+#undef RETURN
+#define RETURN(_code) do { \
+ rval.code = _code; \
+ rval.consumed = consumed_myself;\
+ return rval; \
+ } while(0)
+
+/*
+ * The decoder of the SET OF type.
+ */
+asn_dec_rval_t
+SET_OF_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ void **struct_ptr, const void *ptr, size_t size, int tag_mode) {
+ /*
+ * Bring closer parts of structure description.
+ */
+ asn_SET_OF_specifics_t *specs = (asn_SET_OF_specifics_t *)td->specifics;
+ asn_TYPE_member_t *elm = td->elements; /* Single one */
+
+ /*
+ * Parts of the structure being constructed.
+ */
+ void *st = *struct_ptr; /* Target structure. */
+ asn_struct_ctx_t *ctx; /* Decoder context */
+
+ ber_tlv_tag_t tlv_tag; /* T from TLV */
+ asn_dec_rval_t rval; /* Return code from subparsers */
+
+ ssize_t consumed_myself = 0; /* Consumed bytes from ptr */
+
+ ASN_DEBUG("Decoding %s as SET OF", td->name);
+
+ /*
+ * Create the target structure if it is not present already.
+ */
+ if(st == 0) {
+ st = *struct_ptr = CALLOC(1, specs->struct_size);
+ if(st == 0) {
+ RETURN(RC_FAIL);
+ }
+ }
+
+ /*
+ * Restore parsing context.
+ */
+ ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset);
+
+ /*
+ * Start to parse where left previously
+ */
+ switch(ctx->phase) {
+ case 0:
+ /*
+ * PHASE 0.
+ * Check that the set of tags associated with given structure
+ * perfectly fits our expectations.
+ */
+
+ rval = ber_check_tags(opt_codec_ctx, td, ctx, ptr, size,
+ tag_mode, 1, &ctx->left, 0);
+ if(rval.code != RC_OK) {
+ ASN_DEBUG("%s tagging check failed: %d",
+ td->name, rval.code);
+ return rval;
+ }
+
+ if(ctx->left >= 0)
+ ctx->left += rval.consumed; /* ?Substracted below! */
+ ADVANCE(rval.consumed);
+
+ ASN_DEBUG("Structure consumes %ld bytes, "
+ "buffer %ld", (long)ctx->left, (long)size);
+
+ NEXT_PHASE(ctx);
+ /* Fall through */
+ case 1:
+ /*
+ * PHASE 1.
+ * From the place where we've left it previously,
+ * try to decode the next item.
+ */
+ for(;; ctx->step = 0) {
+ ssize_t tag_len; /* Length of TLV's T */
+
+ if(ctx->step & 1)
+ goto microphase2;
+
+ /*
+ * MICROPHASE 1: Synchronize decoding.
+ */
+
+ if(ctx->left == 0) {
+ ASN_DEBUG("End of SET OF %s", td->name);
+ /*
+ * No more things to decode.
+ * Exit out of here.
+ */
+ PHASE_OUT(ctx);
+ RETURN(RC_OK);
+ }
+
+ /*
+ * Fetch the T from TLV.
+ */
+ tag_len = ber_fetch_tag(ptr, LEFT, &tlv_tag);
+ switch(tag_len) {
+ case 0: if(!SIZE_VIOLATION) RETURN(RC_WMORE);
+ /* Fall through */
+ case -1: RETURN(RC_FAIL);
+ }
+
+ if(ctx->left < 0 && ((const uint8_t *)ptr)[0] == 0) {
+ if(LEFT < 2) {
+ if(SIZE_VIOLATION)
+ RETURN(RC_FAIL);
+ else
+ RETURN(RC_WMORE);
+ } else if(((const uint8_t *)ptr)[1] == 0) {
+ /*
+ * Found the terminator of the
+ * indefinite length structure.
+ */
+ break;
+ }
+ }
+
+ /* Outmost tag may be unknown and cannot be fetched/compared */
+ if(elm->tag != (ber_tlv_tag_t)-1) {
+ if(BER_TAGS_EQUAL(tlv_tag, elm->tag)) {
+ /*
+ * The new list member of expected type has arrived.
+ */
+ } else {
+ ASN_DEBUG("Unexpected tag %s fixed SET OF %s",
+ ber_tlv_tag_string(tlv_tag), td->name);
+ ASN_DEBUG("%s SET OF has tag %s",
+ td->name, ber_tlv_tag_string(elm->tag));
+ RETURN(RC_FAIL);
+ }
+ }
+
+ /*
+ * MICROPHASE 2: Invoke the member-specific decoder.
+ */
+ ctx->step |= 1; /* Confirm entering next microphase */
+ microphase2:
+
+ /*
+ * Invoke the member fetch routine according to member's type
+ */
+ rval = elm->type->ber_decoder(opt_codec_ctx,
+ elm->type, &ctx->ptr, ptr, LEFT, 0);
+ ASN_DEBUG("In %s SET OF %s code %d consumed %d",
+ td->name, elm->type->name,
+ rval.code, (int)rval.consumed);
+ switch(rval.code) {
+ case RC_OK:
+ {
+ asn_anonymous_set_ *list = _A_SET_FROM_VOID(st);
+ if(ASN_SET_ADD(list, ctx->ptr) != 0)
+ RETURN(RC_FAIL);
+ else
+ ctx->ptr = 0;
+ }
+ break;
+ case RC_WMORE: /* More data expected */
+ if(!SIZE_VIOLATION) {
+ ADVANCE(rval.consumed);
+ RETURN(RC_WMORE);
+ }
+ /* Fall through */
+ case RC_FAIL: /* Fatal error */
+ RETURN(RC_FAIL);
+ } /* switch(rval) */
+
+ ADVANCE(rval.consumed);
+ } /* for(all list members) */
+
+ NEXT_PHASE(ctx);
+ case 2:
+ /*
+ * Read in all "end of content" TLVs.
+ */
+ while(ctx->left < 0) {
+ if(LEFT < 2) {
+ if(LEFT > 0 && ((const char *)ptr)[0] != 0) {
+ /* Unexpected tag */
+ RETURN(RC_FAIL);
+ } else {
+ RETURN(RC_WMORE);
+ }
+ }
+ if(((const char *)ptr)[0] == 0
+ && ((const char *)ptr)[1] == 0) {
+ ADVANCE(2);
+ ctx->left++;
+ } else {
+ RETURN(RC_FAIL);
+ }
+ }
+
+ PHASE_OUT(ctx);
+ }
+
+ RETURN(RC_OK);
+}
+
+/*
+ * Internally visible buffer holding a single encoded element.
+ */
+struct _el_buffer {
+ uint8_t *buf;
+ size_t length;
+ size_t size;
+};
+/* Append bytes to the above structure */
+static int _el_addbytes(const void *buffer, size_t size, void *el_buf_ptr) {
+ struct _el_buffer *el_buf = (struct _el_buffer *)el_buf_ptr;
+
+ if(el_buf->length + size > el_buf->size)
+ return -1;
+
+ memcpy(el_buf->buf + el_buf->length, buffer, size);
+
+ el_buf->length += size;
+ return 0;
+}
+static int _el_buf_cmp(const void *ap, const void *bp) {
+ const struct _el_buffer *a = (const struct _el_buffer *)ap;
+ const struct _el_buffer *b = (const struct _el_buffer *)bp;
+ int ret;
+ size_t common_len;
+
+ if(a->length < b->length)
+ common_len = a->length;
+ else
+ common_len = b->length;
+
+ ret = memcmp(a->buf, b->buf, common_len);
+ if(ret == 0) {
+ if(a->length < b->length)
+ ret = -1;
+ else if(a->length > b->length)
+ ret = 1;
+ }
+
+ return ret;
+}
+
+/*
+ * The DER encoder of the SET OF type.
+ */
+asn_enc_rval_t
+SET_OF_encode_der(asn_TYPE_descriptor_t *td, void *ptr,
+ int tag_mode, ber_tlv_tag_t tag,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ asn_TYPE_member_t *elm = td->elements;
+ asn_TYPE_descriptor_t *elm_type = elm->type;
+ der_type_encoder_f *der_encoder = elm_type->der_encoder;
+ asn_anonymous_set_ *list = _A_SET_FROM_VOID(ptr);
+ size_t computed_size = 0;
+ ssize_t encoding_size = 0;
+ struct _el_buffer *encoded_els;
+ ssize_t eels_count = 0;
+ size_t max_encoded_len = 1;
+ asn_enc_rval_t erval;
+ int ret;
+ int edx;
+
+ ASN_DEBUG("Estimating size for SET OF %s", td->name);
+
+ /*
+ * Gather the length of the underlying members sequence.
+ */
+ for(edx = 0; edx < list->count; edx++) {
+ void *memb_ptr = list->array[edx];
+ if(!memb_ptr) continue;
+ erval = der_encoder(elm_type, memb_ptr, 0, elm->tag, 0, 0);
+ if(erval.encoded == -1)
+ return erval;
+ computed_size += erval.encoded;
+
+ /* Compute maximum encoding's size */
+ if(max_encoded_len < (size_t)erval.encoded)
+ max_encoded_len = erval.encoded;
+ }
+
+ /*
+ * Encode the TLV for the sequence itself.
+ */
+ encoding_size = der_write_tags(td, computed_size, tag_mode, 1, tag,
+ cb, app_key);
+ if(encoding_size == -1) {
+ erval.encoded = -1;
+ erval.failed_type = td;
+ erval.structure_ptr = ptr;
+ return erval;
+ }
+ computed_size += encoding_size;
+
+ if(!cb || list->count == 0) {
+ erval.encoded = computed_size;
+ _ASN_ENCODED_OK(erval);
+ }
+
+ /*
+ * DER mandates dynamic sorting of the SET OF elements
+ * according to their encodings. Build an array of the
+ * encoded elements.
+ */
+ encoded_els = (struct _el_buffer *)MALLOC(
+ list->count * sizeof(encoded_els[0]));
+ if(encoded_els == NULL) {
+ erval.encoded = -1;
+ erval.failed_type = td;
+ erval.structure_ptr = ptr;
+ return erval;
+ }
+
+ ASN_DEBUG("Encoding members of %s SET OF", td->name);
+
+ /*
+ * Encode all members.
+ */
+ for(edx = 0; edx < list->count; edx++) {
+ void *memb_ptr = list->array[edx];
+ struct _el_buffer *encoded_el = &encoded_els[eels_count];
+
+ if(!memb_ptr) continue;
+
+ /*
+ * Prepare space for encoding.
+ */
+ encoded_el->buf = (uint8_t *)MALLOC(max_encoded_len);
+ if(encoded_el->buf) {
+ encoded_el->length = 0;
+ encoded_el->size = max_encoded_len;
+ } else {
+ for(edx--; edx >= 0; edx--)
+ FREEMEM(encoded_els[edx].buf);
+ FREEMEM(encoded_els);
+ erval.encoded = -1;
+ erval.failed_type = td;
+ erval.structure_ptr = ptr;
+ return erval;
+ }
+
+ /*
+ * Encode the member into the prepared space.
+ */
+ erval = der_encoder(elm_type, memb_ptr, 0, elm->tag,
+ _el_addbytes, encoded_el);
+ if(erval.encoded == -1) {
+ for(; edx >= 0; edx--)
+ FREEMEM(encoded_els[edx].buf);
+ FREEMEM(encoded_els);
+ return erval;
+ }
+ encoding_size += erval.encoded;
+ eels_count++;
+ }
+
+ /*
+ * Sort the encoded elements according to their encoding.
+ */
+ qsort(encoded_els, eels_count, sizeof(encoded_els[0]), _el_buf_cmp);
+
+ /*
+ * Report encoded elements to the application.
+ * Dispose of temporary sorted members table.
+ */
+ ret = 0;
+ for(edx = 0; edx < eels_count; edx++) {
+ struct _el_buffer *encoded_el = &encoded_els[edx];
+ /* Report encoded chunks to the application */
+ if(ret == 0
+ && cb(encoded_el->buf, encoded_el->length, app_key) < 0)
+ ret = -1;
+ FREEMEM(encoded_el->buf);
+ }
+ FREEMEM(encoded_els);
+
+ if(ret || computed_size != (size_t)encoding_size) {
+ /*
+ * Standard callback failed, or
+ * encoded size is not equal to the computed size.
+ */
+ erval.encoded = -1;
+ erval.failed_type = td;
+ erval.structure_ptr = ptr;
+ } else {
+ erval.encoded = computed_size;
+ }
+
+ _ASN_ENCODED_OK(erval);
+}
+
+#undef XER_ADVANCE
+#define XER_ADVANCE(num_bytes) do { \
+ size_t num = num_bytes; \
+ buf_ptr = ((const char *)buf_ptr) + num;\
+ size -= num; \
+ consumed_myself += num; \
+ } while(0)
+
+/*
+ * Decode the XER (XML) data.
+ */
+asn_dec_rval_t
+SET_OF_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ void **struct_ptr, const char *opt_mname,
+ const void *buf_ptr, size_t size) {
+ /*
+ * Bring closer parts of structure description.
+ */
+ asn_SET_OF_specifics_t *specs = (asn_SET_OF_specifics_t *)td->specifics;
+ asn_TYPE_member_t *element = td->elements;
+ const char *elm_tag;
+ const char *xml_tag = opt_mname ? opt_mname : td->xml_tag;
+
+ /*
+ * ... and parts of the structure being constructed.
+ */
+ void *st = *struct_ptr; /* Target structure. */
+ asn_struct_ctx_t *ctx; /* Decoder context */
+
+ asn_dec_rval_t rval; /* Return value from a decoder */
+ ssize_t consumed_myself = 0; /* Consumed bytes from ptr */
+
+ /*
+ * Create the target structure if it is not present already.
+ */
+ if(st == 0) {
+ st = *struct_ptr = CALLOC(1, specs->struct_size);
+ if(st == 0) RETURN(RC_FAIL);
+ }
+
+ /* Which tag is expected for the downstream */
+ if(specs->as_XMLValueList) {
+ elm_tag = (specs->as_XMLValueList == 1) ? 0 : "";
+ } else {
+ elm_tag = (*element->name)
+ ? element->name : element->type->xml_tag;
+ }
+
+ /*
+ * Restore parsing context.
+ */
+ ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset);
+
+ /*
+ * Phases of XER/XML processing:
+ * Phase 0: Check that the opening tag matches our expectations.
+ * Phase 1: Processing body and reacting on closing tag.
+ * Phase 2: Processing inner type.
+ */
+ for(; ctx->phase <= 2;) {
+ pxer_chunk_type_e ch_type; /* XER chunk type */
+ ssize_t ch_size; /* Chunk size */
+ xer_check_tag_e tcv; /* Tag check value */
+
+ /*
+ * Go inside the inner member of a set.
+ */
+ if(ctx->phase == 2) {
+ asn_dec_rval_t tmprval;
+
+ /* Invoke the inner type decoder, m.b. multiple times */
+ ASN_DEBUG("XER/SET OF element [%s]", elm_tag);
+ tmprval = element->type->xer_decoder(opt_codec_ctx,
+ element->type, &ctx->ptr, elm_tag,
+ buf_ptr, size);
+ if(tmprval.code == RC_OK) {
+ asn_anonymous_set_ *list = _A_SET_FROM_VOID(st);
+ if(ASN_SET_ADD(list, ctx->ptr) != 0)
+ RETURN(RC_FAIL);
+ ctx->ptr = 0;
+ XER_ADVANCE(tmprval.consumed);
+ } else {
+ XER_ADVANCE(tmprval.consumed);
+ RETURN(tmprval.code);
+ }
+ ctx->phase = 1; /* Back to body processing */
+ ASN_DEBUG("XER/SET OF phase => %d", ctx->phase);
+ /* Fall through */
+ }
+
+ /*
+ * Get the next part of the XML stream.
+ */
+ ch_size = xer_next_token(&ctx->context,
+ buf_ptr, size, &ch_type);
+ switch(ch_size) {
+ case -1: RETURN(RC_FAIL);
+ case 0: RETURN(RC_WMORE);
+ default:
+ switch(ch_type) {
+ case PXER_COMMENT: /* Got XML comment */
+ case PXER_TEXT: /* Ignore free-standing text */
+ XER_ADVANCE(ch_size); /* Skip silently */
+ continue;
+ case PXER_TAG:
+ break; /* Check the rest down there */
+ }
+ }
+
+ tcv = xer_check_tag(buf_ptr, ch_size, xml_tag);
+ ASN_DEBUG("XER/SET OF: tcv = %d, ph=%d t=%s",
+ tcv, ctx->phase, xml_tag);
+ switch(tcv) {
+ case XCT_CLOSING:
+ if(ctx->phase == 0) break;
+ ctx->phase = 0;
+ /* Fall through */
+ case XCT_BOTH:
+ if(ctx->phase == 0) {
+ /* No more things to decode */
+ XER_ADVANCE(ch_size);
+ ctx->phase = 3; /* Phase out */
+ RETURN(RC_OK);
+ }
+ /* Fall through */
+ case XCT_OPENING:
+ if(ctx->phase == 0) {
+ XER_ADVANCE(ch_size);
+ ctx->phase = 1; /* Processing body phase */
+ continue;
+ }
+ /* Fall through */
+ case XCT_UNKNOWN_OP:
+ case XCT_UNKNOWN_BO:
+
+ ASN_DEBUG("XER/SET OF: tcv=%d, ph=%d", tcv, ctx->phase);
+ if(ctx->phase == 1) {
+ /*
+ * Process a single possible member.
+ */
+ ctx->phase = 2;
+ continue;
+ }
+ /* Fall through */
+ default:
+ break;
+ }
+
+ ASN_DEBUG("Unexpected XML tag in SET OF");
+ break;
+ }
+
+ ctx->phase = 3; /* "Phase out" on hard failure */
+ RETURN(RC_FAIL);
+}
+
+
+
+typedef struct xer_tmp_enc_s {
+ void *buffer;
+ size_t offset;
+ size_t size;
+} xer_tmp_enc_t;
+static int
+SET_OF_encode_xer_callback(const void *buffer, size_t size, void *key) {
+ xer_tmp_enc_t *t = (xer_tmp_enc_t *)key;
+ if(t->offset + size >= t->size) {
+ size_t newsize = (t->size << 2) + size;
+ void *p = REALLOC(t->buffer, newsize);
+ if(!p) return -1;
+ t->buffer = p;
+ t->size = newsize;
+ }
+ memcpy((char *)t->buffer + t->offset, buffer, size);
+ t->offset += size;
+ return 0;
+}
+static int
+SET_OF_xer_order(const void *aptr, const void *bptr) {
+ const xer_tmp_enc_t *a = (const xer_tmp_enc_t *)aptr;
+ const xer_tmp_enc_t *b = (const xer_tmp_enc_t *)bptr;
+ size_t minlen = a->offset;
+ int ret;
+ if(b->offset < minlen) minlen = b->offset;
+ /* Well-formed UTF-8 has this nice lexicographical property... */
+ ret = memcmp(a->buffer, b->buffer, minlen);
+ if(ret != 0) return ret;
+ if(a->offset == b->offset)
+ return 0;
+ if(a->offset == minlen)
+ return -1;
+ return 1;
+}
+
+
+asn_enc_rval_t
+SET_OF_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ asn_enc_rval_t er;
+ asn_SET_OF_specifics_t *specs = (asn_SET_OF_specifics_t *)td->specifics;
+ asn_TYPE_member_t *elm = td->elements;
+ asn_anonymous_set_ *list = _A_SET_FROM_VOID(sptr);
+ const char *mname = specs->as_XMLValueList
+ ? 0 : ((*elm->name) ? elm->name : elm->type->xml_tag);
+ size_t mlen = mname ? strlen(mname) : 0;
+ int xcan = (flags & XER_F_CANONICAL);
+ xer_tmp_enc_t *encs = 0;
+ size_t encs_count = 0;
+ void *original_app_key = app_key;
+ asn_app_consume_bytes_f *original_cb = cb;
+ int i;
+
+ if(!sptr) _ASN_ENCODE_FAILED;
+
+ if(xcan) {
+ encs = (xer_tmp_enc_t *)MALLOC(list->count * sizeof(encs[0]));
+ if(!encs) _ASN_ENCODE_FAILED;
+ cb = SET_OF_encode_xer_callback;
+ }
+
+ er.encoded = 0;
+
+ for(i = 0; i < list->count; i++) {
+ asn_enc_rval_t tmper;
+
+ void *memb_ptr = list->array[i];
+ if(!memb_ptr) continue;
+
+ if(encs) {
+ memset(&encs[encs_count], 0, sizeof(encs[0]));
+ app_key = &encs[encs_count];
+ encs_count++;
+ }
+
+ if(mname) {
+ if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel);
+ _ASN_CALLBACK3("<", 1, mname, mlen, ">", 1);
+ }
+
+ if(!xcan && specs->as_XMLValueList == 1)
+ _i_ASN_TEXT_INDENT(1, ilevel + 1);
+ tmper = elm->type->xer_encoder(elm->type, memb_ptr,
+ ilevel + (specs->as_XMLValueList != 2),
+ flags, cb, app_key);
+ if(tmper.encoded == -1) {
+ td = tmper.failed_type;
+ sptr = tmper.structure_ptr;
+ goto cb_failed;
+ }
+ if(tmper.encoded == 0 && specs->as_XMLValueList) {
+ const char *name = elm->type->xml_tag;
+ size_t len = strlen(name);
+ _ASN_CALLBACK3("<", 1, name, len, "/>", 2);
+ }
+
+ if(mname) {
+ _ASN_CALLBACK3("</", 2, mname, mlen, ">", 1);
+ er.encoded += 5;
+ }
+
+ er.encoded += (2 * mlen) + tmper.encoded;
+ }
+
+ if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel - 1);
+
+ if(encs) {
+ xer_tmp_enc_t *enc = encs;
+ xer_tmp_enc_t *end = encs + encs_count;
+ ssize_t control_size = 0;
+
+ cb = original_cb;
+ app_key = original_app_key;
+ qsort(encs, encs_count, sizeof(encs[0]), SET_OF_xer_order);
+
+ for(; enc < end; enc++) {
+ _ASN_CALLBACK(enc->buffer, enc->offset);
+ FREEMEM(enc->buffer);
+ enc->buffer = 0;
+ control_size += enc->offset;
+ }
+ assert(control_size == er.encoded);
+ }
+
+ goto cleanup;
+cb_failed:
+ er.encoded = -1;
+ er.failed_type = td;
+ er.structure_ptr = sptr;
+cleanup:
+ if(encs) {
+ while(encs_count-- > 0) {
+ if(encs[encs_count].buffer)
+ FREEMEM(encs[encs_count].buffer);
+ }
+ FREEMEM(encs);
+ }
+ _ASN_ENCODED_OK(er);
+}
+
+int
+SET_OF_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ asn_TYPE_member_t *elm = td->elements;
+ const asn_anonymous_set_ *list = _A_CSET_FROM_VOID(sptr);
+ int ret;
+ int i;
+
+ if(!sptr) return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
+
+ /* Dump preamble */
+ if(cb(td->name, strlen(td->name), app_key) < 0
+ || cb(" ::= {", 6, app_key) < 0)
+ return -1;
+
+ for(i = 0; i < list->count; i++) {
+ const void *memb_ptr = list->array[i];
+ if(!memb_ptr) continue;
+
+ _i_INDENT(1);
+
+ ret = elm->type->print_struct(elm->type, memb_ptr,
+ ilevel + 1, cb, app_key);
+ if(ret) return ret;
+ }
+
+ ilevel--;
+ _i_INDENT(1);
+
+ return (cb("}", 1, app_key) < 0) ? -1 : 0;
+}
+
+void
+SET_OF_free(asn_TYPE_descriptor_t *td, void *ptr, int contents_only) {
+ if(td && ptr) {
+ asn_TYPE_member_t *elm = td->elements;
+ asn_anonymous_set_ *list = _A_SET_FROM_VOID(ptr);
+ int i;
+
+ /*
+ * Could not use set_of_empty() because of (*free)
+ * incompatibility.
+ */
+ for(i = 0; i < list->count; i++) {
+ void *memb_ptr = list->array[i];
+ if(memb_ptr)
+ ASN_STRUCT_FREE(*elm->type, memb_ptr);
+ }
+ list->count = 0; /* No meaningful elements left */
+
+ asn_set_empty(list); /* Remove (list->array) */
+
+ if(!contents_only) {
+ FREEMEM(ptr);
+ }
+ }
+}
+
+int
+SET_OF_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
+ asn_app_constraint_failed_f *ctfailcb, void *app_key) {
+ asn_TYPE_member_t *elm = td->elements;
+ asn_constr_check_f *constr;
+ const asn_anonymous_set_ *list = _A_CSET_FROM_VOID(sptr);
+ int i;
+
+ if(!sptr) {
+ _ASN_CTFAIL(app_key, td,
+ "%s: value not given (%s:%d)",
+ td->name, __FILE__, __LINE__);
+ return -1;
+ }
+
+ constr = elm->memb_constraints;
+ if(!constr) constr = elm->type->check_constraints;
+
+ /*
+ * Iterate over the members of an array.
+ * Validate each in turn, until one fails.
+ */
+ for(i = 0; i < list->count; i++) {
+ const void *memb_ptr = list->array[i];
+ int ret;
+
+ if(!memb_ptr) continue;
+
+ ret = constr(elm->type, memb_ptr, ctfailcb, app_key);
+ if(ret) return ret;
+ }
+
+ /*
+ * Cannot inherit it eralier:
+ * need to make sure we get the updated version.
+ */
+ if(!elm->memb_constraints)
+ elm->memb_constraints = elm->type->check_constraints;
+
+ return 0;
+}
+
+asn_dec_rval_t
+SET_OF_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
+ asn_dec_rval_t rv;
+ asn_SET_OF_specifics_t *specs = (asn_SET_OF_specifics_t *)td->specifics;
+ asn_TYPE_member_t *elm = td->elements; /* Single one */
+ void *st = *sptr;
+ asn_anonymous_set_ *list;
+ asn_per_constraint_t *ct;
+ int repeat = 0;
+ ssize_t nelems;
+
+ if(_ASN_STACK_OVERFLOW_CHECK(opt_codec_ctx))
+ _ASN_DECODE_FAILED;
+
+ /*
+ * Create the target structure if it is not present already.
+ */
+ if(!st) {
+ st = *sptr = CALLOC(1, specs->struct_size);
+ if(!st) _ASN_DECODE_FAILED;
+ }
+ list = _A_SET_FROM_VOID(st);
+
+ /* Figure out which constraints to use */
+ if(constraints) ct = &constraints->size;
+ else if(td->per_constraints) ct = &td->per_constraints->size;
+ else ct = 0;
+
+ if(ct && ct->flags & APC_EXTENSIBLE) {
+ int value = per_get_few_bits(pd, 1);
+ if(value < 0) _ASN_DECODE_STARVED;
+ if(value) ct = 0; /* Not restricted! */
+ }
+
+ if(ct && ct->effective_bits >= 0) {
+ /* X.691, #19.5: No length determinant */
+ nelems = per_get_few_bits(pd, ct->effective_bits);
+ ASN_DEBUG("Preparing to fetch %ld+%ld elements from %s",
+ (long)nelems, ct->lower_bound, td->name);
+ if(nelems < 0) _ASN_DECODE_STARVED;
+ nelems += ct->lower_bound;
+ } else {
+ nelems = -1;
+ }
+
+ do {
+ int i;
+ if(nelems < 0) {
+ nelems = uper_get_length(pd,
+ ct ? ct->effective_bits : -1, &repeat);
+ ASN_DEBUG("Got to decode %d elements (eff %d)",
+ (int)nelems, (int)ct ? ct->effective_bits : -1);
+ if(nelems < 0) _ASN_DECODE_STARVED;
+ }
+
+ for(i = 0; i < nelems; i++) {
+ void *ptr = 0;
+ ASN_DEBUG("SET OF %s decoding", elm->type->name);
+ rv = elm->type->uper_decoder(opt_codec_ctx, elm->type,
+ elm->per_constraints, &ptr, pd);
+ ASN_DEBUG("%s SET OF %s decoded %d, %p",
+ td->name, elm->type->name, rv.code, ptr);
+ if(rv.code == RC_OK) {
+ if(ASN_SET_ADD(list, ptr) == 0)
+ continue;
+ ASN_DEBUG("Failed to add element into %s",
+ td->name);
+ /* Fall through */
+ rv.code == RC_FAIL;
+ } else {
+ ASN_DEBUG("Failed decoding %s of %s (SET OF)",
+ elm->type->name, td->name);
+ }
+ if(ptr) ASN_STRUCT_FREE(*elm->type, ptr);
+ return rv;
+ }
+
+ nelems = -1; /* Allow uper_get_length() */
+ } while(repeat);
+
+ ASN_DEBUG("Decoded %s as SET OF", td->name);
+
+ rv.code = RC_OK;
+ rv.consumed = 0;
+ return rv;
+}
+
--- /dev/null
+/*-
+ * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#include <asn_internal.h>
+#include <constr_TYPE.h>
+#include <errno.h>
+
+/*
+ * Version of the ASN.1 infrastructure shipped with compiler.
+ */
+int get_asn1c_environment_version() { return ASN1C_ENVIRONMENT_VERSION; }
+
+static asn_app_consume_bytes_f _print2fp;
+
+/*
+ * Return the outmost tag of the type.
+ */
+ber_tlv_tag_t
+asn_TYPE_outmost_tag(asn_TYPE_descriptor_t *type_descriptor,
+ const void *struct_ptr, int tag_mode, ber_tlv_tag_t tag) {
+
+ if(tag_mode)
+ return tag;
+
+ if(type_descriptor->tags_count)
+ return type_descriptor->tags[0];
+
+ return type_descriptor->outmost_tag(type_descriptor, struct_ptr, 0, 0);
+}
+
+/*
+ * Print the target language's structure in human readable form.
+ */
+int
+asn_fprint(FILE *stream, asn_TYPE_descriptor_t *td, const void *struct_ptr) {
+ if(!stream) stream = stdout;
+ if(!td || !struct_ptr) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ /* Invoke type-specific printer */
+ if(td->print_struct(td, struct_ptr, 1, _print2fp, stream))
+ return -1;
+
+ /* Terminate the output */
+ if(_print2fp("\n", 1, stream))
+ return -1;
+
+ return fflush(stream);
+}
+
+/* Dump the data into the specified stdio stream */
+static int
+_print2fp(const void *buffer, size_t size, void *app_key) {
+ FILE *stream = (FILE *)app_key;
+
+ if(fwrite(buffer, 1, size, stream) != size)
+ return -1;
+
+ return 0;
+}
+
+
+/*
+ * Some compilers do not support variable args macros.
+ * This function is a replacement of ASN_DEBUG() macro.
+ */
+void ASN_DEBUG_f(const char *fmt, ...);
+void ASN_DEBUG_f(const char *fmt, ...) {
+ va_list ap;
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ fprintf(stderr, "\n");
+ va_end(ap);
+}
--- /dev/null
+#include "asn_internal.h"
+#include "constraints.h"
+
+int
+asn_generic_no_constraint(asn_TYPE_descriptor_t *type_descriptor,
+ const void *struct_ptr, asn_app_constraint_failed_f *cb, void *key) {
+
+ (void)type_descriptor; /* Unused argument */
+ (void)struct_ptr; /* Unused argument */
+ (void)cb; /* Unused argument */
+ (void)key; /* Unused argument */
+
+ /* Nothing to check */
+ return 0;
+}
+
+int
+asn_generic_unknown_constraint(asn_TYPE_descriptor_t *type_descriptor,
+ const void *struct_ptr, asn_app_constraint_failed_f *cb, void *key) {
+
+ (void)type_descriptor; /* Unused argument */
+ (void)struct_ptr; /* Unused argument */
+ (void)cb; /* Unused argument */
+ (void)key; /* Unused argument */
+
+ /* Unknown how to check */
+ return 0;
+}
+
+struct errbufDesc {
+ asn_TYPE_descriptor_t *failed_type;
+ const void *failed_struct_ptr;
+ char *errbuf;
+ size_t errlen;
+};
+
+static void
+_asn_i_ctfailcb(void *key, asn_TYPE_descriptor_t *td, const void *sptr, const char *fmt, ...) {
+ struct errbufDesc *arg = key;
+ va_list ap;
+ ssize_t vlen;
+ ssize_t maxlen;
+
+ arg->failed_type = td;
+ arg->failed_struct_ptr = sptr;
+
+ maxlen = arg->errlen;
+ if(maxlen <= 0)
+ return;
+
+ va_start(ap, fmt);
+ vlen = vsnprintf(arg->errbuf, maxlen, fmt, ap);
+ va_end(ap);
+ if(vlen >= maxlen) {
+ arg->errbuf[maxlen-1] = '\0'; /* Ensuring libc correctness */
+ arg->errlen = maxlen - 1; /* Not counting termination */
+ return;
+ } else if(vlen >= 0) {
+ arg->errbuf[vlen] = '\0'; /* Ensuring libc correctness */
+ arg->errlen = vlen; /* Not counting termination */
+ } else {
+ /*
+ * The libc on this system is broken.
+ */
+ vlen = sizeof("<broken vsnprintf>") - 1;
+ maxlen--;
+ arg->errlen = vlen < maxlen ? vlen : maxlen;
+ memcpy(arg->errbuf, "<broken vsnprintf>", arg->errlen);
+ arg->errbuf[arg->errlen] = 0;
+ }
+
+ return;
+}
+
+int
+asn_check_constraints(asn_TYPE_descriptor_t *type_descriptor,
+ const void *struct_ptr, char *errbuf, size_t *errlen) {
+ struct errbufDesc arg;
+ int ret;
+
+ arg.failed_type = 0;
+ arg.failed_struct_ptr = 0;
+ arg.errbuf = errbuf;
+ arg.errlen = errlen ? *errlen : 0;
+
+ ret = type_descriptor->check_constraints(type_descriptor,
+ struct_ptr, _asn_i_ctfailcb, &arg);
+ if(ret == -1 && errlen)
+ *errlen = arg.errlen;
+
+ return ret;
+}
+
--- /dev/null
+/*-
+ * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#include <asn_internal.h>
+#include <errno.h>
+
+static ssize_t der_write_TL(ber_tlv_tag_t tag, ber_tlv_len_t len,
+ asn_app_consume_bytes_f *cb, void *app_key, int constructed);
+
+/*
+ * The DER encoder of any type.
+ */
+asn_enc_rval_t
+der_encode(asn_TYPE_descriptor_t *type_descriptor, void *struct_ptr,
+ asn_app_consume_bytes_f *consume_bytes, void *app_key) {
+
+ ASN_DEBUG("DER encoder invoked for %s",
+ type_descriptor->name);
+
+ /*
+ * Invoke type-specific encoder.
+ */
+ return type_descriptor->der_encoder(type_descriptor,
+ struct_ptr, /* Pointer to the destination structure */
+ 0, 0,
+ consume_bytes, app_key);
+}
+
+/*
+ * Argument type and callback necessary for der_encode_to_buffer().
+ */
+typedef struct enc_to_buf_arg {
+ void *buffer;
+ size_t left;
+} enc_to_buf_arg;
+static int encode_to_buffer_cb(const void *buffer, size_t size, void *key) {
+ enc_to_buf_arg *arg = (enc_to_buf_arg *)key;
+
+ if(arg->left < size)
+ return -1; /* Data exceeds the available buffer size */
+
+ memcpy(arg->buffer, buffer, size);
+ arg->buffer = ((char *)arg->buffer) + size;
+ arg->left -= size;
+
+ return 0;
+}
+
+/*
+ * A variant of the der_encode() which encodes the data into the provided buffer
+ */
+asn_enc_rval_t
+der_encode_to_buffer(asn_TYPE_descriptor_t *type_descriptor, void *struct_ptr,
+ void *buffer, size_t buffer_size) {
+ enc_to_buf_arg arg;
+ asn_enc_rval_t ec;
+
+ arg.buffer = buffer;
+ arg.left = buffer_size;
+
+ ec = type_descriptor->der_encoder(type_descriptor,
+ struct_ptr, /* Pointer to the destination structure */
+ 0, 0, encode_to_buffer_cb, &arg);
+ if(ec.encoded != -1) {
+ assert(ec.encoded == (ssize_t)(buffer_size - arg.left));
+ /* Return the encoded contents size */
+ }
+ return ec;
+}
+
+
+/*
+ * Write out leading TL[v] sequence according to the type definition.
+ */
+ssize_t
+der_write_tags(asn_TYPE_descriptor_t *sd,
+ size_t struct_length,
+ int tag_mode, int last_tag_form,
+ ber_tlv_tag_t tag, /* EXPLICIT or IMPLICIT tag */
+ asn_app_consume_bytes_f *cb,
+ void *app_key) {
+ ber_tlv_tag_t *tags; /* Copy of tags stream */
+ int tags_count; /* Number of tags */
+ size_t overall_length;
+ ssize_t *lens;
+ int i;
+
+ ASN_DEBUG("Writing tags (%s, tm=%d, tc=%d, tag=%s, mtc=%d)",
+ sd->name, tag_mode, sd->tags_count,
+ ber_tlv_tag_string(tag),
+ tag_mode
+ ?(sd->tags_count+1
+ -((tag_mode == -1) && sd->tags_count))
+ :sd->tags_count
+ );
+
+ if(tag_mode) {
+ /*
+ * Instead of doing shaman dance like we do in ber_check_tags(),
+ * allocate a small array on the stack
+ * and initialize it appropriately.
+ */
+ int stag_offset;
+ tags = (ber_tlv_tag_t *)alloca((sd->tags_count + 1) * sizeof(ber_tlv_tag_t));
+ if(!tags) { /* Can fail on !x86 */
+ errno = ENOMEM;
+ return -1;
+ }
+ tags_count = sd->tags_count
+ + 1 /* EXPLICIT or IMPLICIT tag is given */
+ - ((tag_mode == -1) && sd->tags_count);
+ /* Copy tags over */
+ tags[0] = tag;
+ stag_offset = -1 + ((tag_mode == -1) && sd->tags_count);
+ for(i = 1; i < tags_count; i++)
+ tags[i] = sd->tags[i + stag_offset];
+ } else {
+ tags = sd->tags;
+ tags_count = sd->tags_count;
+ }
+
+ /* No tags to write */
+ if(tags_count == 0)
+ return 0;
+
+ lens = (ssize_t *)alloca(tags_count * sizeof(lens[0]));
+ if(!lens) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ /*
+ * Array of tags is initialized.
+ * Now, compute the size of the TLV pairs, from right to left.
+ */
+ overall_length = struct_length;
+ for(i = tags_count - 1; i >= 0; --i) {
+ lens[i] = der_write_TL(tags[i], overall_length, 0, 0, 0);
+ if(lens[i] == -1) return -1;
+ overall_length += lens[i];
+ lens[i] = overall_length - lens[i];
+ }
+
+ if(!cb) return overall_length - struct_length;
+
+ ASN_DEBUG("%s %s TL sequence (%d elements)",
+ cb?"Encoding":"Estimating", sd->name, tags_count);
+
+ /*
+ * Encode the TL sequence for real.
+ */
+ for(i = 0; i < tags_count; i++) {
+ ssize_t len;
+ int _constr;
+
+ /* Check if this tag happens to be constructed */
+ _constr = (last_tag_form || i < (tags_count - 1));
+
+ len = der_write_TL(tags[i], lens[i], cb, app_key, _constr);
+ if(len == -1) return -1;
+ }
+
+ return overall_length - struct_length;
+}
+
+static ssize_t
+der_write_TL(ber_tlv_tag_t tag, ber_tlv_len_t len,
+ asn_app_consume_bytes_f *cb, void *app_key,
+ int constructed) {
+ uint8_t buf[32];
+ size_t size = 0;
+ int buf_size = cb?sizeof(buf):0;
+ ssize_t tmp;
+
+ /* Serialize tag (T from TLV) into possibly zero-length buffer */
+ tmp = ber_tlv_tag_serialize(tag, buf, buf_size);
+ if(tmp == -1 || tmp > (ssize_t)sizeof(buf)) return -1;
+ size += tmp;
+
+ /* Serialize length (L from TLV) into possibly zero-length buffer */
+ tmp = der_tlv_length_serialize(len, buf+size, buf_size?buf_size-size:0);
+ if(tmp == -1) return -1;
+ size += tmp;
+
+ if(size > sizeof(buf))
+ return -1;
+
+ /*
+ * If callback is specified, invoke it, and check its return value.
+ */
+ if(cb) {
+ if(constructed) *buf |= 0x20;
+ if(cb(buf, size, app_key) < 0)
+ return -1;
+ }
+
+ return size;
+}
--- /dev/null
+/*-
+ * Copyright (c) 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#ifndef ASN_TYPE_ANY_H
+#define ASN_TYPE_ANY_H
+
+#include <OCTET_STRING.h> /* Implemented via OCTET STRING type */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct ANY {
+ uint8_t *buf; /* BER-encoded ANY contents */
+ int size; /* Size of the above buffer */
+
+ asn_struct_ctx_t _asn_ctx; /* Parsing across buffer boundaries */
+} ANY_t;
+
+extern asn_TYPE_descriptor_t asn_DEF_ANY;
+
+asn_struct_free_f ANY_free;
+asn_struct_print_f ANY_print;
+ber_type_decoder_f ANY_decode_ber;
+der_type_encoder_f ANY_encode_der;
+xer_type_encoder_f ANY_encode_xer;
+
+/******************************
+ * Handy conversion routines. *
+ ******************************/
+
+/* Convert another ASN.1 type into the ANY. This implies DER encoding. */
+int ANY_fromType(ANY_t *, asn_TYPE_descriptor_t *td, void *struct_ptr);
+ANY_t *ANY_new_fromType(asn_TYPE_descriptor_t *td, void *struct_ptr);
+
+/* Convert the contents of the ANY type into the specified type. */
+int ANY_to_type(ANY_t *, asn_TYPE_descriptor_t *td, void **struct_ptr);
+
+#define ANY_fromBuf(s, buf, size) OCTET_STRING_fromBuf((s), (buf), (size))
+#define ANY_new_fromBuf(buf, size) OCTET_STRING_new_fromBuf( \
+ &asn_DEF_ANY, (buf), (size))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ASN_TYPE_ANY_H */
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1155-SMI"
+ * found in "RFC1155-SMI.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#ifndef _ApplicationSyntax_H_
+#define _ApplicationSyntax_H_
+
+
+#include <asn_application.h>
+
+/* Including external dependencies */
+#include "NetworkAddress.h"
+#include "Counter.h"
+#include "Gauge.h"
+#include "TimeTicks.h"
+#include "Opaque.h"
+#include <constr_CHOICE.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Dependencies */
+typedef enum ApplicationSyntax_PR {
+ ApplicationSyntax_PR_NOTHING, /* No components present */
+ ApplicationSyntax_PR_address,
+ ApplicationSyntax_PR_counter,
+ ApplicationSyntax_PR_gauge,
+ ApplicationSyntax_PR_ticks,
+ ApplicationSyntax_PR_arbitrary
+} ApplicationSyntax_PR;
+
+/* ApplicationSyntax */
+typedef struct ApplicationSyntax {
+ ApplicationSyntax_PR present;
+ union ApplicationSyntax_u {
+ NetworkAddress_t address;
+ Counter_t counter;
+ Gauge_t gauge;
+ TimeTicks_t ticks;
+ Opaque_t arbitrary;
+ } choice;
+
+ /* Context for parsing across buffer boundaries */
+ asn_struct_ctx_t _asn_ctx;
+} ApplicationSyntax_t;
+
+/* Implementation */
+extern asn_TYPE_descriptor_t asn_DEF_ApplicationSyntax;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ApplicationSyntax_H_ */
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1213-MIB"
+ * found in "RFC1213-MIB.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#ifndef _AtEntry_H_
+#define _AtEntry_H_
+
+
+#include <asn_application.h>
+
+/* Including external dependencies */
+#include <INTEGER.h>
+#include "PhysAddress.h"
+#include "NetworkAddress.h"
+#include <constr_SEQUENCE.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* AtEntry */
+typedef struct AtEntry {
+ INTEGER_t atIfIndex;
+ PhysAddress_t atPhysAddress;
+ NetworkAddress_t atNetAddress;
+
+ /* Context for parsing across buffer boundaries */
+ asn_struct_ctx_t _asn_ctx;
+} AtEntry_t;
+
+/* Implementation */
+extern asn_TYPE_descriptor_t asn_DEF_AtEntry;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _AtEntry_H_ */
--- /dev/null
+/*-
+ * Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#ifndef _BIT_STRING_H_
+#define _BIT_STRING_H_
+
+#include <OCTET_STRING.h> /* Some help from OCTET STRING */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct BIT_STRING_s {
+ uint8_t *buf; /* BIT STRING body */
+ int size; /* Size of the above buffer */
+
+ int bits_unused;/* Unused trailing bits in the last octet (0..7) */
+
+ asn_struct_ctx_t _asn_ctx; /* Parsing across buffer boundaries */
+} BIT_STRING_t;
+
+extern asn_TYPE_descriptor_t asn_DEF_BIT_STRING;
+
+asn_struct_print_f BIT_STRING_print; /* Human-readable output */
+asn_constr_check_f BIT_STRING_constraint;
+xer_type_encoder_f BIT_STRING_encode_xer;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _BIT_STRING_H_ */
--- /dev/null
+/*-
+ * Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#ifndef _BOOLEAN_H_
+#define _BOOLEAN_H_
+
+#include <asn_application.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * The underlying integer may contain various values, but everything
+ * non-zero is capped to 0xff by the DER encoder. The BER decoder may
+ * yield non-zero values different from 1, beware.
+ */
+typedef int BOOLEAN_t;
+
+extern asn_TYPE_descriptor_t asn_DEF_BOOLEAN;
+
+asn_struct_free_f BOOLEAN_free;
+asn_struct_print_f BOOLEAN_print;
+ber_type_decoder_f BOOLEAN_decode_ber;
+der_type_encoder_f BOOLEAN_encode_der;
+xer_type_decoder_f BOOLEAN_decode_xer;
+xer_type_encoder_f BOOLEAN_encode_xer;
+per_type_decoder_f BOOLEAN_decode_uper;
+per_type_encoder_f BOOLEAN_encode_uper;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _BOOLEAN_H_ */
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "SMUX"
+ * found in "SMUX.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#ifndef _ClosePDU_H_
+#define _ClosePDU_H_
+
+
+#include <asn_application.h>
+
+/* Including external dependencies */
+#include <INTEGER.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Dependencies */
+typedef enum ClosePDU {
+ ClosePDU_goingDown = 0,
+ ClosePDU_unsupportedVersion = 1,
+ ClosePDU_packetFormat = 2,
+ ClosePDU_protocolError = 3,
+ ClosePDU_internalError = 4,
+ ClosePDU_authenticationFailure = 5
+} e_ClosePDU;
+
+/* ClosePDU */
+typedef INTEGER_t ClosePDU_t;
+
+/* Implementation */
+extern asn_TYPE_descriptor_t asn_DEF_ClosePDU;
+asn_struct_free_f ClosePDU_free;
+asn_struct_print_f ClosePDU_print;
+asn_constr_check_f ClosePDU_constraint;
+ber_type_decoder_f ClosePDU_decode_ber;
+der_type_encoder_f ClosePDU_encode_der;
+xer_type_decoder_f ClosePDU_decode_xer;
+xer_type_encoder_f ClosePDU_encode_xer;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ClosePDU_H_ */
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1155-SMI"
+ * found in "RFC1155-SMI.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#ifndef _Counter_H_
+#define _Counter_H_
+
+
+#include <asn_application.h>
+
+/* Including external dependencies */
+#include <INTEGER.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Counter */
+typedef INTEGER_t Counter_t;
+
+/* Implementation */
+extern asn_TYPE_descriptor_t asn_DEF_Counter;
+asn_struct_free_f Counter_free;
+asn_struct_print_f Counter_print;
+asn_constr_check_f Counter_constraint;
+ber_type_decoder_f Counter_decode_ber;
+der_type_encoder_f Counter_encode_der;
+xer_type_decoder_f Counter_decode_xer;
+xer_type_encoder_f Counter_encode_xer;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _Counter_H_ */
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1213-MIB"
+ * found in "RFC1213-MIB.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#ifndef _DisplayString_H_
+#define _DisplayString_H_
+
+
+#include <asn_application.h>
+
+/* Including external dependencies */
+#include <OCTET_STRING.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* DisplayString */
+typedef OCTET_STRING_t DisplayString_t;
+
+/* Implementation */
+extern asn_TYPE_descriptor_t asn_DEF_DisplayString;
+asn_struct_free_f DisplayString_free;
+asn_struct_print_f DisplayString_print;
+asn_constr_check_f DisplayString_constraint;
+ber_type_decoder_f DisplayString_decode_ber;
+der_type_encoder_f DisplayString_encode_der;
+xer_type_decoder_f DisplayString_decode_xer;
+xer_type_encoder_f DisplayString_encode_xer;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _DisplayString_H_ */
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1213-MIB"
+ * found in "RFC1213-MIB.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#ifndef _EgpNeighEntry_H_
+#define _EgpNeighEntry_H_
+
+
+#include <asn_application.h>
+
+/* Including external dependencies */
+#include <INTEGER.h>
+#include "IpAddress.h"
+#include "Counter.h"
+#include <constr_SEQUENCE.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* EgpNeighEntry */
+typedef struct EgpNeighEntry {
+ INTEGER_t egpNeighState;
+ IpAddress_t egpNeighAddr;
+ INTEGER_t egpNeighAs;
+ Counter_t egpNeighInMsgs;
+ Counter_t egpNeighInErrs;
+ Counter_t egpNeighOutMsgs;
+ Counter_t egpNeighOutErrs;
+ Counter_t egpNeighInErrMsgs;
+ Counter_t egpNeighOutErrMsgs;
+ Counter_t egpNeighStateUps;
+ Counter_t egpNeighStateDowns;
+ INTEGER_t egpNeighIntervalHello;
+ INTEGER_t egpNeighIntervalPoll;
+ INTEGER_t egpNeighMode;
+ INTEGER_t egpNeighEventTrigger;
+
+ /* Context for parsing across buffer boundaries */
+ asn_struct_ctx_t _asn_ctx;
+} EgpNeighEntry_t;
+
+/* Implementation */
+extern asn_TYPE_descriptor_t asn_DEF_EgpNeighEntry;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _EgpNeighEntry_H_ */
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1155-SMI"
+ * found in "RFC1155-SMI.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#ifndef _Gauge_H_
+#define _Gauge_H_
+
+
+#include <asn_application.h>
+
+/* Including external dependencies */
+#include <INTEGER.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Gauge */
+typedef INTEGER_t Gauge_t;
+
+/* Implementation */
+extern asn_TYPE_descriptor_t asn_DEF_Gauge;
+asn_struct_free_f Gauge_free;
+asn_struct_print_f Gauge_print;
+asn_constr_check_f Gauge_constraint;
+ber_type_decoder_f Gauge_decode_ber;
+der_type_encoder_f Gauge_encode_der;
+xer_type_decoder_f Gauge_decode_xer;
+xer_type_encoder_f Gauge_encode_xer;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _Gauge_H_ */
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1157-SNMP"
+ * found in "RFC1157-SNMP.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#ifndef _GetNextRequest_PDU_H_
+#define _GetNextRequest_PDU_H_
+
+
+#include <asn_application.h>
+
+/* Including external dependencies */
+#include "PDU.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* GetNextRequest-PDU */
+typedef PDU_t GetNextRequest_PDU_t;
+
+/* Implementation */
+extern asn_TYPE_descriptor_t asn_DEF_GetNextRequest_PDU;
+asn_struct_free_f GetNextRequest_PDU_free;
+asn_struct_print_f GetNextRequest_PDU_print;
+asn_constr_check_f GetNextRequest_PDU_constraint;
+ber_type_decoder_f GetNextRequest_PDU_decode_ber;
+der_type_encoder_f GetNextRequest_PDU_encode_der;
+xer_type_decoder_f GetNextRequest_PDU_decode_xer;
+xer_type_encoder_f GetNextRequest_PDU_encode_xer;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _GetNextRequest_PDU_H_ */
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1157-SNMP"
+ * found in "RFC1157-SNMP.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#ifndef _GetRequest_PDU_H_
+#define _GetRequest_PDU_H_
+
+
+#include <asn_application.h>
+
+/* Including external dependencies */
+#include "PDU.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* GetRequest-PDU */
+typedef PDU_t GetRequest_PDU_t;
+
+/* Implementation */
+extern asn_TYPE_descriptor_t asn_DEF_GetRequest_PDU;
+asn_struct_free_f GetRequest_PDU_free;
+asn_struct_print_f GetRequest_PDU_print;
+asn_constr_check_f GetRequest_PDU_constraint;
+ber_type_decoder_f GetRequest_PDU_decode_ber;
+der_type_encoder_f GetRequest_PDU_encode_der;
+xer_type_decoder_f GetRequest_PDU_decode_xer;
+xer_type_encoder_f GetRequest_PDU_encode_xer;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _GetRequest_PDU_H_ */
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1157-SNMP"
+ * found in "RFC1157-SNMP.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#ifndef _GetResponse_PDU_H_
+#define _GetResponse_PDU_H_
+
+
+#include <asn_application.h>
+
+/* Including external dependencies */
+#include "PDU.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* GetResponse-PDU */
+typedef PDU_t GetResponse_PDU_t;
+
+/* Implementation */
+extern asn_TYPE_descriptor_t asn_DEF_GetResponse_PDU;
+asn_struct_free_f GetResponse_PDU_free;
+asn_struct_print_f GetResponse_PDU_print;
+asn_constr_check_f GetResponse_PDU_constraint;
+ber_type_decoder_f GetResponse_PDU_decode_ber;
+der_type_encoder_f GetResponse_PDU_encode_der;
+xer_type_decoder_f GetResponse_PDU_decode_xer;
+xer_type_encoder_f GetResponse_PDU_encode_xer;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _GetResponse_PDU_H_ */
--- /dev/null
+/*-
+ * Copyright (c) 2003, 2005 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#ifndef _INTEGER_H_
+#define _INTEGER_H_
+
+#include <asn_application.h>
+#include <asn_codecs_prim.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef ASN__PRIMITIVE_TYPE_t INTEGER_t;
+
+extern asn_TYPE_descriptor_t asn_DEF_INTEGER;
+
+/* Map with <tag> to integer value association */
+typedef struct asn_INTEGER_enum_map_s {
+ long nat_value; /* associated native integer value */
+ size_t enum_len; /* strlen("tag") */
+ const char *enum_name; /* "tag" */
+} asn_INTEGER_enum_map_t;
+
+/* This type describes an enumeration for INTEGER and ENUMERATED types */
+typedef struct asn_INTEGER_specifics_s {
+ asn_INTEGER_enum_map_t *value2enum; /* N -> "tag"; sorted by N */
+ unsigned int *enum2value; /* "tag" => N; sorted by tag */
+ int map_count; /* Elements in either map */
+ int extension; /* This map is extensible */
+ int strict_enumeration; /* Enumeration set is fixed */
+} asn_INTEGER_specifics_t;
+
+asn_struct_print_f INTEGER_print;
+ber_type_decoder_f INTEGER_decode_ber;
+der_type_encoder_f INTEGER_encode_der;
+xer_type_decoder_f INTEGER_decode_xer;
+xer_type_encoder_f INTEGER_encode_xer;
+per_type_decoder_f INTEGER_decode_uper;
+per_type_encoder_f INTEGER_encode_uper;
+
+/***********************************
+ * Some handy conversion routines. *
+ ***********************************/
+
+/*
+ * Returns 0 if it was possible to convert, -1 otherwise.
+ * -1/EINVAL: Mandatory argument missing
+ * -1/ERANGE: Value encoded is out of range for long representation
+ * -1/ENOMEM: Memory allocation failed (in asn_long2INTEGER()).
+ */
+int asn_INTEGER2long(const INTEGER_t *i, long *l);
+int asn_long2INTEGER(INTEGER_t *i, long l);
+
+/*
+ * Convert the integer value into the corresponding enumeration map entry.
+ */
+const asn_INTEGER_enum_map_t *INTEGER_map_value2enum(asn_INTEGER_specifics_t *specs, long value);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _INTEGER_H_ */
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1213-MIB"
+ * found in "RFC1213-MIB.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#ifndef _IfEntry_H_
+#define _IfEntry_H_
+
+
+#include <asn_application.h>
+
+/* Including external dependencies */
+#include <INTEGER.h>
+#include "DisplayString.h"
+#include "Gauge.h"
+#include "PhysAddress.h"
+#include "TimeTicks.h"
+#include "Counter.h"
+#include <OBJECT_IDENTIFIER.h>
+#include <constr_SEQUENCE.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* IfEntry */
+typedef struct IfEntry {
+ INTEGER_t ifIndex;
+ DisplayString_t ifDescr;
+ INTEGER_t ifType;
+ INTEGER_t ifMtu;
+ Gauge_t ifSpeed;
+ PhysAddress_t ifPhysAddress;
+ INTEGER_t ifAdminStatus;
+ INTEGER_t ifOperStatus;
+ TimeTicks_t ifLastChange;
+ Counter_t ifInOctets;
+ Counter_t ifInUcastPkts;
+ Counter_t ifInNUcastPkts;
+ Counter_t ifInDiscards;
+ Counter_t ifInErrors;
+ Counter_t ifInUnknownProtos;
+ Counter_t ifOutOctets;
+ Counter_t ifOutUcastPkts;
+ Counter_t ifOutNUcastPkts;
+ Counter_t ifOutDiscards;
+ Counter_t ifOutErrors;
+ Gauge_t ifOutQLen;
+ OBJECT_IDENTIFIER_t ifSpecific;
+
+ /* Context for parsing across buffer boundaries */
+ asn_struct_ctx_t _asn_ctx;
+} IfEntry_t;
+
+/* Implementation */
+extern asn_TYPE_descriptor_t asn_DEF_IfEntry;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _IfEntry_H_ */
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1213-MIB"
+ * found in "RFC1213-MIB.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#ifndef _IpAddrEntry_H_
+#define _IpAddrEntry_H_
+
+
+#include <asn_application.h>
+
+/* Including external dependencies */
+#include "IpAddress.h"
+#include <INTEGER.h>
+#include <NativeInteger.h>
+#include <constr_SEQUENCE.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* IpAddrEntry */
+typedef struct IpAddrEntry {
+ IpAddress_t ipAdEntAddr;
+ INTEGER_t ipAdEntIfIndex;
+ IpAddress_t ipAdEntNetMask;
+ INTEGER_t ipAdEntBcastAddr;
+ long ipAdEntReasmMaxSize;
+
+ /* Context for parsing across buffer boundaries */
+ asn_struct_ctx_t _asn_ctx;
+} IpAddrEntry_t;
+
+/* Implementation */
+extern asn_TYPE_descriptor_t asn_DEF_IpAddrEntry;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _IpAddrEntry_H_ */
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1155-SMI"
+ * found in "RFC1155-SMI.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#ifndef _IpAddress_H_
+#define _IpAddress_H_
+
+
+#include <asn_application.h>
+
+/* Including external dependencies */
+#include <OCTET_STRING.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* IpAddress */
+typedef OCTET_STRING_t IpAddress_t;
+
+/* Implementation */
+extern asn_TYPE_descriptor_t asn_DEF_IpAddress;
+asn_struct_free_f IpAddress_free;
+asn_struct_print_f IpAddress_print;
+asn_constr_check_f IpAddress_constraint;
+ber_type_decoder_f IpAddress_decode_ber;
+der_type_encoder_f IpAddress_encode_der;
+xer_type_decoder_f IpAddress_decode_xer;
+xer_type_encoder_f IpAddress_encode_xer;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _IpAddress_H_ */
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1213-MIB"
+ * found in "RFC1213-MIB.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#ifndef _IpNetToMediaEntry_H_
+#define _IpNetToMediaEntry_H_
+
+
+#include <asn_application.h>
+
+/* Including external dependencies */
+#include <INTEGER.h>
+#include "PhysAddress.h"
+#include "IpAddress.h"
+#include <constr_SEQUENCE.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* IpNetToMediaEntry */
+typedef struct IpNetToMediaEntry {
+ INTEGER_t ipNetToMediaIfIndex;
+ PhysAddress_t ipNetToMediaPhysAddress;
+ IpAddress_t ipNetToMediaNetAddress;
+ INTEGER_t ipNetToMediaType;
+
+ /* Context for parsing across buffer boundaries */
+ asn_struct_ctx_t _asn_ctx;
+} IpNetToMediaEntry_t;
+
+/* Implementation */
+extern asn_TYPE_descriptor_t asn_DEF_IpNetToMediaEntry;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _IpNetToMediaEntry_H_ */
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1213-MIB"
+ * found in "RFC1213-MIB.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#ifndef _IpRouteEntry_H_
+#define _IpRouteEntry_H_
+
+
+#include <asn_application.h>
+
+/* Including external dependencies */
+#include "IpAddress.h"
+#include <INTEGER.h>
+#include <OBJECT_IDENTIFIER.h>
+#include <constr_SEQUENCE.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* IpRouteEntry */
+typedef struct IpRouteEntry {
+ IpAddress_t ipRouteDest;
+ INTEGER_t ipRouteIfIndex;
+ INTEGER_t ipRouteMetric1;
+ INTEGER_t ipRouteMetric2;
+ INTEGER_t ipRouteMetric3;
+ INTEGER_t ipRouteMetric4;
+ IpAddress_t ipRouteNextHop;
+ INTEGER_t ipRouteType;
+ INTEGER_t ipRouteProto;
+ INTEGER_t ipRouteAge;
+ IpAddress_t ipRouteMask;
+ INTEGER_t ipRouteMetric5;
+ OBJECT_IDENTIFIER_t ipRouteInfo;
+
+ /* Context for parsing across buffer boundaries */
+ asn_struct_ctx_t _asn_ctx;
+} IpRouteEntry_t;
+
+/* Implementation */
+extern asn_TYPE_descriptor_t asn_DEF_IpRouteEntry;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _IpRouteEntry_H_ */
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1157-SNMP"
+ * found in "RFC1157-SNMP.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#ifndef _Message_H_
+#define _Message_H_
+
+
+#include <asn_application.h>
+
+/* Including external dependencies */
+#include <INTEGER.h>
+#include <OCTET_STRING.h>
+#include <ANY.h>
+#include <constr_SEQUENCE.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Dependencies */
+typedef enum Message__version {
+ Message__version_version_1 = 0
+} e_Message__version;
+
+/* Message */
+typedef struct Message {
+ INTEGER_t version;
+ OCTET_STRING_t community;
+ ANY_t data;
+
+ /* Context for parsing across buffer boundaries */
+ asn_struct_ctx_t _asn_ctx;
+} Message_t;
+
+/* Implementation */
+extern asn_TYPE_descriptor_t asn_DEF_Message;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _Message_H_ */
--- /dev/null
+/*-
+ * Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#ifndef ASN_TYPE_NULL_H
+#define ASN_TYPE_NULL_H
+
+#include <asn_application.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * The value of the NULL type is meaningless: see BOOLEAN if you want to
+ * carry true/false semantics.
+ */
+typedef int NULL_t;
+
+extern asn_TYPE_descriptor_t asn_DEF_NULL;
+
+asn_struct_print_f NULL_print;
+der_type_encoder_f NULL_encode_der;
+xer_type_decoder_f NULL_decode_xer;
+xer_type_encoder_f NULL_encode_xer;
+per_type_decoder_f NULL_decode_uper;
+per_type_encoder_f NULL_encode_uper;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NULL_H */
--- /dev/null
+/*-
+ * Copyright (c) 2004, 2005, 2006 Lev Walkin <vlm@lionet.info>.
+ * All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+/*
+ * This type differs from the standard ENUMERATED in that it is modelled using
+ * the fixed machine type (long, int, short), so it can hold only values of
+ * limited length. There is no type (i.e., NativeEnumerated_t, any integer type
+ * will do).
+ * This type may be used when integer range is limited by subtype constraints.
+ */
+#ifndef _NativeEnumerated_H_
+#define _NativeEnumerated_H_
+
+#include <NativeInteger.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern asn_TYPE_descriptor_t asn_DEF_NativeEnumerated;
+
+xer_type_encoder_f NativeEnumerated_encode_xer;
+per_type_decoder_f NativeEnumerated_decode_uper;
+per_type_encoder_f NativeEnumerated_encode_uper;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _NativeEnumerated_H_ */
--- /dev/null
+/*-
+ * Copyright (c) 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+/*
+ * This type differs from the standard INTEGER in that it is modelled using
+ * the fixed machine type (long, int, short), so it can hold only values of
+ * limited length. There is no type (i.e., NativeInteger_t, any integer type
+ * will do).
+ * This type may be used when integer range is limited by subtype constraints.
+ */
+#ifndef _NativeInteger_H_
+#define _NativeInteger_H_
+
+#include <asn_application.h>
+#include <INTEGER.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern asn_TYPE_descriptor_t asn_DEF_NativeInteger;
+
+asn_struct_free_f NativeInteger_free;
+asn_struct_print_f NativeInteger_print;
+ber_type_decoder_f NativeInteger_decode_ber;
+der_type_encoder_f NativeInteger_encode_der;
+xer_type_decoder_f NativeInteger_decode_xer;
+xer_type_encoder_f NativeInteger_encode_xer;
+per_type_decoder_f NativeInteger_decode_uper;
+per_type_encoder_f NativeInteger_encode_uper;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _NativeInteger_H_ */
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1155-SMI"
+ * found in "RFC1155-SMI.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#ifndef _NetworkAddress_H_
+#define _NetworkAddress_H_
+
+
+#include <asn_application.h>
+
+/* Including external dependencies */
+#include "IpAddress.h"
+#include <constr_CHOICE.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Dependencies */
+typedef enum NetworkAddress_PR {
+ NetworkAddress_PR_NOTHING, /* No components present */
+ NetworkAddress_PR_internet
+} NetworkAddress_PR;
+
+/* NetworkAddress */
+typedef struct NetworkAddress {
+ NetworkAddress_PR present;
+ union NetworkAddress_u {
+ IpAddress_t internet;
+ } choice;
+
+ /* Context for parsing across buffer boundaries */
+ asn_struct_ctx_t _asn_ctx;
+} NetworkAddress_t;
+
+/* Implementation */
+extern asn_TYPE_descriptor_t asn_DEF_NetworkAddress;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _NetworkAddress_H_ */
--- /dev/null
+/*-
+ * Copyright (c) 2003, 2004, 2005 Lev Walkin <vlm@lionet.info>.
+ * All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#ifndef _OBJECT_IDENTIFIER_H_
+#define _OBJECT_IDENTIFIER_H_
+
+#include <asn_application.h>
+#include <asn_codecs_prim.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef ASN__PRIMITIVE_TYPE_t OBJECT_IDENTIFIER_t;
+
+extern asn_TYPE_descriptor_t asn_DEF_OBJECT_IDENTIFIER;
+
+asn_struct_print_f OBJECT_IDENTIFIER_print;
+asn_constr_check_f OBJECT_IDENTIFIER_constraint;
+der_type_encoder_f OBJECT_IDENTIFIER_encode_der;
+xer_type_decoder_f OBJECT_IDENTIFIER_decode_xer;
+xer_type_encoder_f OBJECT_IDENTIFIER_encode_xer;
+
+/**********************************
+ * Some handy conversion routines *
+ **********************************/
+
+/*
+ * This function fills an (_arcs) array with OBJECT IDENTIFIER arcs
+ * up to specified (_arc_slots) elements.
+ *
+ * EXAMPLE:
+ * void print_arcs(OBJECT_IDENTIFIER_t *oid) {
+ * unsigned long fixed_arcs[10]; // Try with fixed space first
+ * unsigned long *arcs = fixed_arcs;
+ * int arc_type_size = sizeof(fixed_arcs[0]); // sizeof(long)
+ * int arc_slots = sizeof(fixed_arcs)/sizeof(fixed_arcs[0]); // 10
+ * int count; // Real number of arcs.
+ * int i;
+ *
+ * count = OBJECT_IDENTIFIER_get_arcs(oid, arcs,
+ * arc_type_size, arc_slots);
+ * // If necessary, reallocate arcs array and try again.
+ * if(count > arc_slots) {
+ * arc_slots = count;
+ * arcs = malloc(arc_type_size * arc_slots);
+ * if(!arcs) return;
+ * count = OBJECT_IDENTIFIER_get_arcs(oid, arcs,
+ * arc_type_size, arc_slots);
+ * assert(count == arc_slots);
+ * }
+ *
+ * // Print the contents of the arcs array.
+ * for(i = 0; i < count; i++)
+ * printf("%d\n", arcs[i]);
+ *
+ * // Avoid memory leak.
+ * if(arcs != fixed_arcs) free(arcs);
+ * }
+ *
+ * RETURN VALUES:
+ * -1/EINVAL: Invalid arguments (oid is missing)
+ * -1/ERANGE: One or more arcs have value out of array cell type range.
+ * >=0: Number of arcs contained in the OBJECT IDENTIFIER
+ *
+ * WARNING: The function always returns the real number of arcs,
+ * even if there is no sufficient (_arc_slots) provided.
+ */
+int OBJECT_IDENTIFIER_get_arcs(OBJECT_IDENTIFIER_t *_oid,
+ void *_arcs, /* e.g., unsigned int arcs[N] */
+ unsigned int _arc_type_size, /* e.g., sizeof(arcs[0]) */
+ unsigned int _arc_slots /* e.g., N */);
+
+/*
+ * This functions initializes the OBJECT IDENTIFIER object with
+ * the given set of arcs.
+ * The minimum of two arcs must be present; some restrictions apply.
+ * RETURN VALUES:
+ * -1/EINVAL: Invalid arguments
+ * -1/ERANGE: The first two arcs do not conform to ASN.1 restrictions.
+ * -1/ENOMEM: Memory allocation failed
+ * 0: The object was initialized with new arcs.
+ */
+int OBJECT_IDENTIFIER_set_arcs(OBJECT_IDENTIFIER_t *_oid,
+ const void *_arcs, /* e.g., unsigned int arcs[N] */
+ unsigned int _arc_type_size, /* e.g., sizeof(arcs[0]) */
+ unsigned int _arc_slots /* e.g., N */);
+
+/*
+ * Print the specified OBJECT IDENTIFIER arc.
+ */
+int OBJECT_IDENTIFIER_print_arc(uint8_t *arcbuf, int arclen,
+ int add, /* Arbitrary offset, required to process the first two arcs */
+ asn_app_consume_bytes_f *cb, void *app_key);
+
+/* Same as above, but returns the number of written digits, instead of 0 */
+ssize_t OBJECT_IDENTIFIER__dump_arc(uint8_t *arcbuf, int arclen, int add,
+ asn_app_consume_bytes_f *cb, void *app_key);
+
+/*
+ * Parse the OBJECT IDENTIFIER textual representation ("1.3.6.1.4.1.9363").
+ * No arc can exceed the (0..signed_long_max) range (typically, 0..2G if L32).
+ * This function is not specific to OBJECT IDENTIFIER, it may be used to parse
+ * the RELATIVE-OID data, or any other data consisting of dot-separated
+ * series of numeric values.
+ *
+ * If (oid_txt_length == -1), the strlen() will be invoked to determine the
+ * size of the (oid_text) string.
+ *
+ * After return, the optional (opt_oid_text_end) is set to the character after
+ * the last parsed one. (opt_oid_text_end) is never less than (oid_text).
+ *
+ * RETURN VALUES:
+ * -1: Parse error.
+ * >= 0: Number of arcs contained in the OBJECT IDENTIFIER.
+ *
+ * WARNING: The function always returns the real number of arcs,
+ * even if there is no sufficient (_arc_slots) provided.
+ * This is useful for (_arc_slots) value estimation.
+ */
+int OBJECT_IDENTIFIER_parse_arcs(const char *oid_text, ssize_t oid_txt_length,
+ long arcs[], unsigned int arcs_slots, const char **opt_oid_text_end);
+
+/*
+ * Internal functions.
+ * Used by RELATIVE-OID implementation in particular.
+ */
+int OBJECT_IDENTIFIER_get_single_arc(uint8_t *arcbuf, unsigned int arclen,
+ signed int add, void *value, unsigned int value_size);
+int OBJECT_IDENTIFIER_set_single_arc(uint8_t *arcbuf,
+ const void *arcval, unsigned int arcval_size, int _prepared_order);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _OBJECT_IDENTIFIER_H_ */
--- /dev/null
+/*-
+ * Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#ifndef _OCTET_STRING_H_
+#define _OCTET_STRING_H_
+
+#include <asn_application.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct OCTET_STRING {
+ uint8_t *buf; /* Buffer with consecutive OCTET_STRING bits */
+ int size; /* Size of the buffer */
+
+ asn_struct_ctx_t _asn_ctx; /* Parsing across buffer boundaries */
+} OCTET_STRING_t;
+
+extern asn_TYPE_descriptor_t asn_DEF_OCTET_STRING;
+
+asn_struct_free_f OCTET_STRING_free;
+asn_struct_print_f OCTET_STRING_print;
+asn_struct_print_f OCTET_STRING_print_utf8;
+ber_type_decoder_f OCTET_STRING_decode_ber;
+der_type_encoder_f OCTET_STRING_encode_der;
+xer_type_decoder_f OCTET_STRING_decode_xer_hex; /* Hexadecimal */
+xer_type_decoder_f OCTET_STRING_decode_xer_binary; /* 01010111010 */
+xer_type_decoder_f OCTET_STRING_decode_xer_utf8; /* ASCII/UTF-8 */
+xer_type_encoder_f OCTET_STRING_encode_xer;
+xer_type_encoder_f OCTET_STRING_encode_xer_utf8;
+per_type_decoder_f OCTET_STRING_decode_uper;
+per_type_encoder_f OCTET_STRING_encode_uper;
+
+/******************************
+ * Handy conversion routines. *
+ ******************************/
+
+/*
+ * This function clears the previous value of the OCTET STRING (if any)
+ * and then allocates a new memory with the specified content (str/size).
+ * If size = -1, the size of the original string will be determined
+ * using strlen(str).
+ * If str equals to NULL, the function will silently clear the
+ * current contents of the OCTET STRING.
+ * Returns 0 if it was possible to perform operation, -1 otherwise.
+ */
+int OCTET_STRING_fromBuf(OCTET_STRING_t *s, const char *str, int size);
+
+/* Handy conversion from the C string into the OCTET STRING. */
+#define OCTET_STRING_fromString(s, str) OCTET_STRING_fromBuf(s, str, -1)
+
+/*
+ * Allocate and fill the new OCTET STRING and return a pointer to the newly
+ * allocated object. NULL is permitted in str: the function will just allocate
+ * empty OCTET STRING.
+ */
+OCTET_STRING_t *OCTET_STRING_new_fromBuf(asn_TYPE_descriptor_t *td,
+ const char *str, int size);
+
+/****************************
+ * Internally useful stuff. *
+ ****************************/
+
+typedef struct asn_OCTET_STRING_specifics_s {
+ /*
+ * Target structure description.
+ */
+ int struct_size; /* Size of the structure */
+ int ctx_offset; /* Offset of the asn_struct_ctx_t member */
+
+ int subvariant; /* {0,1,2} for O-S, BIT STRING or ANY */
+} asn_OCTET_STRING_specifics_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _OCTET_STRING_H_ */
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1155-SMI"
+ * found in "RFC1155-SMI.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#ifndef _ObjectName_H_
+#define _ObjectName_H_
+
+
+#include <asn_application.h>
+
+/* Including external dependencies */
+#include <OBJECT_IDENTIFIER.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* ObjectName */
+typedef OBJECT_IDENTIFIER_t ObjectName_t;
+
+/* Implementation */
+extern asn_TYPE_descriptor_t asn_DEF_ObjectName;
+asn_struct_free_f ObjectName_free;
+asn_struct_print_f ObjectName_print;
+asn_constr_check_f ObjectName_constraint;
+ber_type_decoder_f ObjectName_decode_ber;
+der_type_encoder_f ObjectName_encode_der;
+xer_type_decoder_f ObjectName_decode_xer;
+xer_type_encoder_f ObjectName_encode_xer;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ObjectName_H_ */
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1155-SMI"
+ * found in "RFC1155-SMI.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#ifndef _ObjectSyntax_H_
+#define _ObjectSyntax_H_
+
+
+#include <asn_application.h>
+
+/* Including external dependencies */
+#include "SimpleSyntax.h"
+#include "ApplicationSyntax.h"
+#include <constr_CHOICE.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Dependencies */
+typedef enum ObjectSyntax_PR {
+ ObjectSyntax_PR_NOTHING, /* No components present */
+ ObjectSyntax_PR_simple,
+ ObjectSyntax_PR_application_wide
+} ObjectSyntax_PR;
+
+/* ObjectSyntax */
+typedef struct ObjectSyntax {
+ ObjectSyntax_PR present;
+ union ObjectSyntax_u {
+ SimpleSyntax_t simple;
+ ApplicationSyntax_t application_wide;
+ } choice;
+
+ /* Context for parsing across buffer boundaries */
+ asn_struct_ctx_t _asn_ctx;
+} ObjectSyntax_t;
+
+/* Implementation */
+extern asn_TYPE_descriptor_t asn_DEF_ObjectSyntax;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ObjectSyntax_H_ */
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1155-SMI"
+ * found in "RFC1155-SMI.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#ifndef _Opaque_H_
+#define _Opaque_H_
+
+
+#include <asn_application.h>
+
+/* Including external dependencies */
+#include <OCTET_STRING.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Opaque */
+typedef OCTET_STRING_t Opaque_t;
+
+/* Implementation */
+extern asn_TYPE_descriptor_t asn_DEF_Opaque;
+asn_struct_free_f Opaque_free;
+asn_struct_print_f Opaque_print;
+asn_constr_check_f Opaque_constraint;
+ber_type_decoder_f Opaque_decode_ber;
+der_type_encoder_f Opaque_encode_der;
+xer_type_decoder_f Opaque_decode_xer;
+xer_type_encoder_f Opaque_encode_xer;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _Opaque_H_ */
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "SMUX"
+ * found in "SMUX.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#ifndef _OpenPDU_H_
+#define _OpenPDU_H_
+
+
+#include <asn_application.h>
+
+/* Including external dependencies */
+#include "SimpleOpen.h"
+#include <constr_CHOICE.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Dependencies */
+typedef enum OpenPDU_PR {
+ OpenPDU_PR_NOTHING, /* No components present */
+ OpenPDU_PR_simple
+} OpenPDU_PR;
+
+/* OpenPDU */
+typedef struct OpenPDU {
+ OpenPDU_PR present;
+ union OpenPDU_u {
+ SimpleOpen_t simple;
+ } choice;
+
+ /* Context for parsing across buffer boundaries */
+ asn_struct_ctx_t _asn_ctx;
+} OpenPDU_t;
+
+/* Implementation */
+extern asn_TYPE_descriptor_t asn_DEF_OpenPDU;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _OpenPDU_H_ */
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1157-SNMP"
+ * found in "RFC1157-SNMP.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#ifndef _PDU_H_
+#define _PDU_H_
+
+
+#include <asn_application.h>
+
+/* Including external dependencies */
+#include <INTEGER.h>
+#include "VarBindList.h"
+#include <constr_SEQUENCE.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Dependencies */
+typedef enum PDU__error_status {
+ PDU__error_status_noError = 0,
+ PDU__error_status_tooBig = 1,
+ PDU__error_status_noSuchName = 2,
+ PDU__error_status_badValue = 3,
+ PDU__error_status_readOnly = 4,
+ PDU__error_status_genErr = 5
+} e_PDU__error_status;
+
+/* PDU */
+typedef struct PDU {
+ INTEGER_t request_id;
+ INTEGER_t error_status;
+ INTEGER_t error_index;
+ VarBindList_t variable_bindings;
+
+ /* Context for parsing across buffer boundaries */
+ asn_struct_ctx_t _asn_ctx;
+} PDU_t;
+
+/* Implementation */
+extern asn_TYPE_descriptor_t asn_DEF_PDU;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _PDU_H_ */
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1157-SNMP"
+ * found in "RFC1157-SNMP.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#ifndef _PDUs_H_
+#define _PDUs_H_
+
+
+#include <asn_application.h>
+
+/* Including external dependencies */
+#include "GetRequest-PDU.h"
+#include "GetNextRequest-PDU.h"
+#include "GetResponse-PDU.h"
+#include "SetRequest-PDU.h"
+#include "Trap-PDU.h"
+#include <constr_CHOICE.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Dependencies */
+typedef enum PDUs_PR {
+ PDUs_PR_NOTHING, /* No components present */
+ PDUs_PR_get_request,
+ PDUs_PR_get_next_request,
+ PDUs_PR_get_response,
+ PDUs_PR_set_request,
+ PDUs_PR_trap
+} PDUs_PR;
+
+/* PDUs */
+typedef struct PDUs {
+ PDUs_PR present;
+ union PDUs_u {
+ GetRequest_PDU_t get_request;
+ GetNextRequest_PDU_t get_next_request;
+ GetResponse_PDU_t get_response;
+ SetRequest_PDU_t set_request;
+ Trap_PDU_t trap;
+ } choice;
+
+ /* Context for parsing across buffer boundaries */
+ asn_struct_ctx_t _asn_ctx;
+} PDUs_t;
+
+/* Implementation */
+extern asn_TYPE_descriptor_t asn_DEF_PDUs;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _PDUs_H_ */
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1213-MIB"
+ * found in "RFC1213-MIB.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#ifndef _PhysAddress_H_
+#define _PhysAddress_H_
+
+
+#include <asn_application.h>
+
+/* Including external dependencies */
+#include <OCTET_STRING.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* PhysAddress */
+typedef OCTET_STRING_t PhysAddress_t;
+
+/* Implementation */
+extern asn_TYPE_descriptor_t asn_DEF_PhysAddress;
+asn_struct_free_f PhysAddress_free;
+asn_struct_print_f PhysAddress_print;
+asn_constr_check_f PhysAddress_constraint;
+ber_type_decoder_f PhysAddress_decode_ber;
+der_type_encoder_f PhysAddress_encode_der;
+xer_type_decoder_f PhysAddress_decode_xer;
+xer_type_encoder_f PhysAddress_encode_xer;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _PhysAddress_H_ */
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "SMUX"
+ * found in "SMUX.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#ifndef _RReqPDU_H_
+#define _RReqPDU_H_
+
+
+#include <asn_application.h>
+
+/* Including external dependencies */
+#include "ObjectName.h"
+#include <NativeInteger.h>
+#include <INTEGER.h>
+#include <constr_SEQUENCE.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Dependencies */
+typedef enum RReqPDU__operation {
+ RReqPDU__operation_delete = 0,
+ RReqPDU__operation_readOnly = 1,
+ RReqPDU__operation_readWrite = 2
+} e_RReqPDU__operation;
+
+/* RReqPDU */
+typedef struct RReqPDU {
+ ObjectName_t subtree;
+ long priority;
+ INTEGER_t operation;
+
+ /* Context for parsing across buffer boundaries */
+ asn_struct_ctx_t _asn_ctx;
+} RReqPDU_t;
+
+/* Implementation */
+extern asn_TYPE_descriptor_t asn_DEF_RReqPDU;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RReqPDU_H_ */
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "SMUX"
+ * found in "SMUX.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#ifndef _RRspPDU_H_
+#define _RRspPDU_H_
+
+
+#include <asn_application.h>
+
+/* Including external dependencies */
+#include <INTEGER.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Dependencies */
+typedef enum RRspPDU {
+ RRspPDU_failure = -1
+} e_RRspPDU;
+
+/* RRspPDU */
+typedef INTEGER_t RRspPDU_t;
+
+/* Implementation */
+extern asn_TYPE_descriptor_t asn_DEF_RRspPDU;
+asn_struct_free_f RRspPDU_free;
+asn_struct_print_f RRspPDU_print;
+asn_constr_check_f RRspPDU_constraint;
+ber_type_decoder_f RRspPDU_decode_ber;
+der_type_encoder_f RRspPDU_encode_der;
+xer_type_decoder_f RRspPDU_decode_xer;
+xer_type_encoder_f RRspPDU_encode_xer;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RRspPDU_H_ */
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "SMUX"
+ * found in "SMUX.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#ifndef _SMUX_PDUs_H_
+#define _SMUX_PDUs_H_
+
+
+#include <asn_application.h>
+
+/* Including external dependencies */
+#include "OpenPDU.h"
+#include "ClosePDU.h"
+#include "RReqPDU.h"
+#include "RRspPDU.h"
+#include "PDUs.h"
+#include "SOutPDU.h"
+#include <constr_CHOICE.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Dependencies */
+typedef enum SMUX_PDUs_PR {
+ SMUX_PDUs_PR_NOTHING, /* No components present */
+ SMUX_PDUs_PR_open,
+ SMUX_PDUs_PR_close,
+ SMUX_PDUs_PR_registerRequest,
+ SMUX_PDUs_PR_registerResponse,
+ SMUX_PDUs_PR_pdus,
+ SMUX_PDUs_PR_commitOrRollback
+} SMUX_PDUs_PR;
+
+/* SMUX-PDUs */
+typedef struct SMUX_PDUs {
+ SMUX_PDUs_PR present;
+ union SMUX_PDUs_u {
+ OpenPDU_t open;
+ ClosePDU_t close;
+ RReqPDU_t registerRequest;
+ RRspPDU_t registerResponse;
+ PDUs_t pdus;
+ SOutPDU_t commitOrRollback;
+ } choice;
+
+ /* Context for parsing across buffer boundaries */
+ asn_struct_ctx_t _asn_ctx;
+} SMUX_PDUs_t;
+
+/* Implementation */
+extern asn_TYPE_descriptor_t asn_DEF_SMUX_PDUs;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SMUX_PDUs_H_ */
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "SMUX"
+ * found in "SMUX.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#ifndef _SOutPDU_H_
+#define _SOutPDU_H_
+
+
+#include <asn_application.h>
+
+/* Including external dependencies */
+#include <INTEGER.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Dependencies */
+typedef enum SOutPDU {
+ SOutPDU_commit = 0,
+ SOutPDU_rollback = 1
+} e_SOutPDU;
+
+/* SOutPDU */
+typedef INTEGER_t SOutPDU_t;
+
+/* Implementation */
+extern asn_TYPE_descriptor_t asn_DEF_SOutPDU;
+asn_struct_free_f SOutPDU_free;
+asn_struct_print_f SOutPDU_print;
+asn_constr_check_f SOutPDU_constraint;
+ber_type_decoder_f SOutPDU_decode_ber;
+der_type_encoder_f SOutPDU_encode_der;
+xer_type_decoder_f SOutPDU_decode_xer;
+xer_type_encoder_f SOutPDU_encode_xer;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SOutPDU_H_ */
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1157-SNMP"
+ * found in "RFC1157-SNMP.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#ifndef _SetRequest_PDU_H_
+#define _SetRequest_PDU_H_
+
+
+#include <asn_application.h>
+
+/* Including external dependencies */
+#include "PDU.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* SetRequest-PDU */
+typedef PDU_t SetRequest_PDU_t;
+
+/* Implementation */
+extern asn_TYPE_descriptor_t asn_DEF_SetRequest_PDU;
+asn_struct_free_f SetRequest_PDU_free;
+asn_struct_print_f SetRequest_PDU_print;
+asn_constr_check_f SetRequest_PDU_constraint;
+ber_type_decoder_f SetRequest_PDU_decode_ber;
+der_type_encoder_f SetRequest_PDU_encode_der;
+xer_type_decoder_f SetRequest_PDU_decode_xer;
+xer_type_encoder_f SetRequest_PDU_encode_xer;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SetRequest_PDU_H_ */
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "SMUX"
+ * found in "SMUX.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#ifndef _SimpleOpen_H_
+#define _SimpleOpen_H_
+
+
+#include <asn_application.h>
+
+/* Including external dependencies */
+#include <INTEGER.h>
+#include <OBJECT_IDENTIFIER.h>
+#include "DisplayString.h"
+#include <OCTET_STRING.h>
+#include <constr_SEQUENCE.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Dependencies */
+typedef enum SimpleOpen__version {
+ SimpleOpen__version_version_1 = 0
+} e_SimpleOpen__version;
+
+/* SimpleOpen */
+typedef struct SimpleOpen {
+ INTEGER_t version;
+ OBJECT_IDENTIFIER_t identity;
+ DisplayString_t description;
+ OCTET_STRING_t password;
+
+ /* Context for parsing across buffer boundaries */
+ asn_struct_ctx_t _asn_ctx;
+} SimpleOpen_t;
+
+/* Implementation */
+extern asn_TYPE_descriptor_t asn_DEF_SimpleOpen;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SimpleOpen_H_ */
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1155-SMI"
+ * found in "RFC1155-SMI.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#ifndef _SimpleSyntax_H_
+#define _SimpleSyntax_H_
+
+
+#include <asn_application.h>
+
+/* Including external dependencies */
+#include <INTEGER.h>
+#include <OCTET_STRING.h>
+#include <OBJECT_IDENTIFIER.h>
+#include <NULL.h>
+#include <constr_CHOICE.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Dependencies */
+typedef enum SimpleSyntax_PR {
+ SimpleSyntax_PR_NOTHING, /* No components present */
+ SimpleSyntax_PR_number,
+ SimpleSyntax_PR_string,
+ SimpleSyntax_PR_object,
+ SimpleSyntax_PR_empty
+} SimpleSyntax_PR;
+
+/* SimpleSyntax */
+typedef struct SimpleSyntax {
+ SimpleSyntax_PR present;
+ union SimpleSyntax_u {
+ INTEGER_t number;
+ OCTET_STRING_t string;
+ OBJECT_IDENTIFIER_t object;
+ NULL_t empty;
+ } choice;
+
+ /* Context for parsing across buffer boundaries */
+ asn_struct_ctx_t _asn_ctx;
+} SimpleSyntax_t;
+
+/* Implementation */
+extern asn_TYPE_descriptor_t asn_DEF_SimpleSyntax;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SimpleSyntax_H_ */
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1213-MIB"
+ * found in "RFC1213-MIB.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#ifndef _TcpConnEntry_H_
+#define _TcpConnEntry_H_
+
+
+#include <asn_application.h>
+
+/* Including external dependencies */
+#include <INTEGER.h>
+#include "IpAddress.h"
+#include <NativeInteger.h>
+#include <constr_SEQUENCE.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* TcpConnEntry */
+typedef struct TcpConnEntry {
+ INTEGER_t tcpConnState;
+ IpAddress_t tcpConnLocalAddress;
+ long tcpConnLocalPort;
+ IpAddress_t tcpConnRemAddress;
+ long tcpConnRemPort;
+
+ /* Context for parsing across buffer boundaries */
+ asn_struct_ctx_t _asn_ctx;
+} TcpConnEntry_t;
+
+/* Implementation */
+extern asn_TYPE_descriptor_t asn_DEF_TcpConnEntry;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TcpConnEntry_H_ */
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1155-SMI"
+ * found in "RFC1155-SMI.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#ifndef _TimeTicks_H_
+#define _TimeTicks_H_
+
+
+#include <asn_application.h>
+
+/* Including external dependencies */
+#include <INTEGER.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* TimeTicks */
+typedef INTEGER_t TimeTicks_t;
+
+/* Implementation */
+extern asn_TYPE_descriptor_t asn_DEF_TimeTicks;
+asn_struct_free_f TimeTicks_free;
+asn_struct_print_f TimeTicks_print;
+asn_constr_check_f TimeTicks_constraint;
+ber_type_decoder_f TimeTicks_decode_ber;
+der_type_encoder_f TimeTicks_encode_der;
+xer_type_decoder_f TimeTicks_decode_xer;
+xer_type_encoder_f TimeTicks_encode_xer;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TimeTicks_H_ */
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1157-SNMP"
+ * found in "RFC1157-SNMP.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#ifndef _Trap_PDU_H_
+#define _Trap_PDU_H_
+
+
+#include <asn_application.h>
+
+/* Including external dependencies */
+#include <OBJECT_IDENTIFIER.h>
+#include "NetworkAddress.h"
+#include <INTEGER.h>
+#include "TimeTicks.h"
+#include "VarBindList.h"
+#include <constr_SEQUENCE.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Dependencies */
+typedef enum Trap_PDU__generic_trap {
+ Trap_PDU__generic_trap_coldStart = 0,
+ Trap_PDU__generic_trap_warmStart = 1,
+ Trap_PDU__generic_trap_linkDown = 2,
+ Trap_PDU__generic_trap_linkUp = 3,
+ Trap_PDU__generic_trap_authenticationFailure = 4,
+ Trap_PDU__generic_trap_egpNeighborLoss = 5,
+ Trap_PDU__generic_trap_enterpriseSpecific = 6
+} e_Trap_PDU__generic_trap;
+
+/* Trap-PDU */
+typedef struct Trap_PDU {
+ OBJECT_IDENTIFIER_t enterprise;
+ NetworkAddress_t agent_addr;
+ INTEGER_t generic_trap;
+ INTEGER_t specific_trap;
+ TimeTicks_t time_stamp;
+ VarBindList_t variable_bindings;
+
+ /* Context for parsing across buffer boundaries */
+ asn_struct_ctx_t _asn_ctx;
+} Trap_PDU_t;
+
+/* Implementation */
+extern asn_TYPE_descriptor_t asn_DEF_Trap_PDU;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _Trap_PDU_H_ */
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1213-MIB"
+ * found in "RFC1213-MIB.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#ifndef _UdpEntry_H_
+#define _UdpEntry_H_
+
+
+#include <asn_application.h>
+
+/* Including external dependencies */
+#include "IpAddress.h"
+#include <NativeInteger.h>
+#include <constr_SEQUENCE.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* UdpEntry */
+typedef struct UdpEntry {
+ IpAddress_t udpLocalAddress;
+ long udpLocalPort;
+
+ /* Context for parsing across buffer boundaries */
+ asn_struct_ctx_t _asn_ctx;
+} UdpEntry_t;
+
+/* Implementation */
+extern asn_TYPE_descriptor_t asn_DEF_UdpEntry;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _UdpEntry_H_ */
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1157-SNMP"
+ * found in "RFC1157-SNMP.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#ifndef _VarBind_H_
+#define _VarBind_H_
+
+
+#include <asn_application.h>
+
+/* Including external dependencies */
+#include "ObjectName.h"
+#include "ObjectSyntax.h"
+#include <constr_SEQUENCE.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* VarBind */
+typedef struct VarBind {
+ ObjectName_t name;
+ ObjectSyntax_t value;
+
+ /* Context for parsing across buffer boundaries */
+ asn_struct_ctx_t _asn_ctx;
+} VarBind_t;
+
+/* Implementation */
+extern asn_TYPE_descriptor_t asn_DEF_VarBind;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _VarBind_H_ */
--- /dev/null
+/*
+ * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * From ASN.1 module "RFC1157-SNMP"
+ * found in "RFC1157-SNMP.asn1"
+ * `asn1c -fskeletons-copy`
+ */
+
+#ifndef _VarBindList_H_
+#define _VarBindList_H_
+
+
+#include <asn_application.h>
+
+/* Including external dependencies */
+#include <asn_SEQUENCE_OF.h>
+#include <constr_SEQUENCE_OF.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Forward declarations */
+struct VarBind;
+
+/* VarBindList */
+typedef struct VarBindList {
+ A_SEQUENCE_OF(struct VarBind) list;
+
+ /* Context for parsing across buffer boundaries */
+ asn_struct_ctx_t _asn_ctx;
+} VarBindList_t;
+
+/* Implementation */
+extern asn_TYPE_descriptor_t asn_DEF_VarBindList;
+
+#ifdef __cplusplus
+}
+#endif
+
+/* Referred external types */
+#include "VarBind.h"
+
+#endif /* _VarBindList_H_ */
--- /dev/null
+/*-
+ * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#ifndef ASN_SEQUENCE_OF_H
+#define ASN_SEQUENCE_OF_H
+
+#include <asn_SET_OF.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * SEQUENCE OF is the same as SET OF with a tiny difference:
+ * the delete operation preserves the initial order of elements
+ * and thus MAY operate in non-constant time.
+ */
+#define A_SEQUENCE_OF(type) A_SET_OF(type)
+
+#define ASN_SEQUENCE_ADD(headptr, ptr) \
+ asn_sequence_add((headptr), (ptr))
+
+/***********************************************
+ * Implementation of the SEQUENCE OF structure.
+ */
+
+#define asn_sequence_add asn_set_add
+#define asn_sequence_empty asn_set_empty
+
+/*
+ * Delete the element from the set by its number (base 0).
+ * This is NOT a constant-time operation.
+ * The order of elements is preserved.
+ * If _do_free is given AND the (*free) is initialized, the element
+ * will be freed using the custom (*free) function as well.
+ */
+void asn_sequence_del(void *asn_sequence_of_x, int number, int _do_free);
+
+/*
+ * Cope with different conversions requirements to/from void in C and C++.
+ * This is mostly useful for support library.
+ */
+typedef A_SEQUENCE_OF(void) asn_anonymous_sequence_;
+#define _A_SEQUENCE_FROM_VOID(ptr) ((asn_anonymous_sequence_ *)(ptr))
+#define _A_CSEQUENCE_FROM_VOID(ptr) ((const asn_anonymous_sequence_ *)(ptr))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ASN_SEQUENCE_OF_H */
--- /dev/null
+/*-
+ * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#ifndef ASN_SET_OF_H
+#define ASN_SET_OF_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define A_SET_OF(type) \
+ struct { \
+ type **array; \
+ int count; /* Meaningful size */ \
+ int size; /* Allocated size */ \
+ void (*free)(type *); \
+ }
+
+#define ASN_SET_ADD(headptr, ptr) \
+ asn_set_add((headptr), (ptr))
+
+/*******************************************
+ * Implementation of the SET OF structure.
+ */
+
+/*
+ * Add another structure into the set by its pointer.
+ * RETURN VALUES:
+ * 0 for success and -1/errno for failure.
+ */
+int asn_set_add(void *asn_set_of_x, void *ptr);
+
+/*
+ * Delete the element from the set by its number (base 0).
+ * This is a constant-time operation. The order of elements before the
+ * deleted ones is guaranteed, the order of elements after the deleted
+ * one is NOT guaranteed.
+ * If _do_free is given AND the (*free) is initialized, the element
+ * will be freed using the custom (*free) function as well.
+ */
+void asn_set_del(void *asn_set_of_x, int number, int _do_free);
+
+/*
+ * Empty the contents of the set. Will free the elements, if (*free) is given.
+ * Will NOT free the set itself.
+ */
+void asn_set_empty(void *asn_set_of_x);
+
+/*
+ * Cope with different conversions requirements to/from void in C and C++.
+ * This is mostly useful for support library.
+ */
+typedef A_SET_OF(void) asn_anonymous_set_;
+#define _A_SET_FROM_VOID(ptr) ((asn_anonymous_set_ *)(ptr))
+#define _A_CSET_FROM_VOID(ptr) ((const asn_anonymous_set_ *)(ptr))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ASN_SET_OF_H */
--- /dev/null
+/*-
+ * Copyright (c) 2004, 2006 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+/*
+ * Application-level ASN.1 callbacks.
+ */
+#ifndef _ASN_APPLICATION_H_
+#define _ASN_APPLICATION_H_
+
+#include "asn_system.h" /* for platform-dependent types */
+#include "asn_codecs.h" /* for ASN.1 codecs specifics */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Generic type of an application-defined callback to return various
+ * types of data to the application.
+ * EXPECTED RETURN VALUES:
+ * -1: Failed to consume bytes. Abort the mission.
+ * Non-negative return values indicate success, and ignored.
+ */
+typedef int (asn_app_consume_bytes_f)(const void *buffer, size_t size,
+ void *application_specific_key);
+
+/*
+ * A callback of this type is called whenever constraint validation fails
+ * on some ASN.1 type. See "constraints.h" for more details on constraint
+ * validation.
+ * This callback specifies a descriptor of the ASN.1 type which failed
+ * the constraint check, as well as human readable message on what
+ * particular constraint has failed.
+ */
+typedef void (asn_app_constraint_failed_f)(void *application_specific_key,
+ struct asn_TYPE_descriptor_s *type_descriptor_which_failed,
+ const void *structure_which_failed_ptr,
+ const char *error_message_format, ...) GCC_PRINTFLIKE(4, 5);
+
+#ifdef __cplusplus
+}
+#endif
+
+#include "constr_TYPE.h" /* for asn_TYPE_descriptor_t */
+
+#endif /* _ASN_APPLICATION_H_ */
--- /dev/null
+/*-
+ * Copyright (c) 2003, 2004, 2005 Lev Walkin <vlm@lionet.info>.
+ * All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#ifndef _ASN_CODECS_H_
+#define _ASN_CODECS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct asn_TYPE_descriptor_s; /* Forward declaration */
+
+/*
+ * This structure defines a set of parameters that may be passed
+ * to every ASN.1 encoder or decoder function.
+ * WARNING: if max_stack_size member is set, and you are calling the
+ * function pointers of the asn_TYPE_descriptor_t directly,
+ * this structure must be ALLOCATED ON THE STACK!
+ * If you can't always satisfy this requirement, use ber_decode(),
+ * xer_decode() and uper_decode() functions instead.
+ */
+typedef struct asn_codec_ctx_s {
+ /*
+ * Limit the decoder routines to use no (much) more stack than a given
+ * number of bytes. Most of decoders are stack-based, and this
+ * would protect against stack overflows if the number of nested
+ * encodings is high.
+ * The OCTET STRING, BIT STRING and ANY BER decoders are heap-based,
+ * and are safe from this kind of overflow.
+ * A value from getrlimit(RLIMIT_STACK) may be used to initialize
+ * this variable. Be careful in multithreaded environments, as the
+ * stack size is rather limited.
+ */
+ size_t max_stack_size; /* 0 disables stack bounds checking */
+} asn_codec_ctx_t;
+
+/*
+ * Type of the return value of the encoding functions (der_encode, xer_encode).
+ */
+typedef struct asn_enc_rval_s {
+ /*
+ * Number of bytes encoded.
+ * -1 indicates failure to encode the structure.
+ * In this case, the members below this one are meaningful.
+ */
+ ssize_t encoded;
+
+ /*
+ * Members meaningful when (encoded == -1), for post mortem analysis.
+ */
+
+ /* Type which cannot be encoded */
+ struct asn_TYPE_descriptor_s *failed_type;
+
+ /* Pointer to the structure of that type */
+ void *structure_ptr;
+} asn_enc_rval_t;
+#define _ASN_ENCODE_FAILED do { \
+ asn_enc_rval_t tmp_error; \
+ tmp_error.encoded = -1; \
+ tmp_error.failed_type = td; \
+ tmp_error.structure_ptr = sptr; \
+ ASN_DEBUG("Failed to encode element %s", td->name); \
+ return tmp_error; \
+} while(0)
+#define _ASN_ENCODED_OK(rval) do { \
+ rval.structure_ptr = 0; \
+ rval.failed_type = 0; \
+ return rval; \
+} while(0)
+
+/*
+ * Type of the return value of the decoding functions (ber_decode, xer_decode)
+ *
+ * Please note that the number of consumed bytes is ALWAYS meaningful,
+ * even if code==RC_FAIL. This is to indicate the number of successfully
+ * decoded bytes, hence providing a possibility to fail with more diagnostics
+ * (i.e., print the offending remainder of the buffer).
+ */
+enum asn_dec_rval_code_e {
+ RC_OK, /* Decoded successfully */
+ RC_WMORE, /* More data expected, call again */
+ RC_FAIL /* Failure to decode data */
+};
+typedef struct asn_dec_rval_s {
+ enum asn_dec_rval_code_e code; /* Result code */
+ size_t consumed; /* Number of bytes consumed */
+} asn_dec_rval_t;
+#define _ASN_DECODE_FAILED do { \
+ asn_dec_rval_t tmp_error; \
+ tmp_error.code = RC_FAIL; \
+ tmp_error.consumed = 0; \
+ ASN_DEBUG("Failed to decode element %s", td->name); \
+ return tmp_error; \
+} while(0)
+#define _ASN_DECODE_STARVED do { \
+ asn_dec_rval_t tmp_error; \
+ tmp_error.code = RC_WMORE; \
+ tmp_error.consumed = 0; \
+ return tmp_error; \
+} while(0)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ASN_CODECS_H_ */
--- /dev/null
+/*-
+ * Copyright (c) 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#ifndef ASN_CODECS_PRIM_H
+#define ASN_CODECS_PRIM_H
+
+#include <asn_application.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct ASN__PRIMITIVE_TYPE_s {
+ uint8_t *buf; /* Buffer with consecutive primitive encoding bytes */
+ int size; /* Size of the buffer */
+} ASN__PRIMITIVE_TYPE_t; /* Do not use this type directly! */
+
+asn_struct_free_f ASN__PRIMITIVE_TYPE_free;
+ber_type_decoder_f ber_decode_primitive;
+der_type_encoder_f der_encode_primitive;
+
+/*
+ * A callback specification for the xer_decode_primitive() function below.
+ */
+enum xer_pbd_rval {
+ XPBD_SYSTEM_FAILURE, /* System failure (memory shortage, etc) */
+ XPBD_DECODER_LIMIT, /* Hit some decoder limitation or deficiency */
+ XPBD_BROKEN_ENCODING, /* Encoding of a primitive body is broken */
+ XPBD_NOT_BODY_IGNORE, /* Not a body format, but safe to ignore */
+ XPBD_BODY_CONSUMED /* Body is recognized and consumed */
+};
+typedef enum xer_pbd_rval (xer_primitive_body_decoder_f)
+ (asn_TYPE_descriptor_t *td, void *struct_ptr,
+ const void *chunk_buf, size_t chunk_size);
+
+/*
+ * Specific function to decode simple primitive types.
+ * Also see xer_decode_general() in xer_decoder.h
+ */
+asn_dec_rval_t xer_decode_primitive(asn_codec_ctx_t *opt_codec_ctx,
+ asn_TYPE_descriptor_t *type_descriptor,
+ void **struct_ptr, size_t struct_size,
+ const char *opt_mname,
+ const void *buf_ptr, size_t size,
+ xer_primitive_body_decoder_f *prim_body_decoder
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ASN_CODECS_PRIM_H */
--- /dev/null
+/*-
+ * Copyright (c) 2003, 2004, 2005 Lev Walkin <vlm@lionet.info>.
+ * All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+/*
+ * Declarations internally useful for the ASN.1 support code.
+ */
+#ifndef _ASN_INTERNAL_H_
+#define _ASN_INTERNAL_H_
+
+#include "asn_application.h" /* Application-visible API */
+
+#ifndef __NO_ASSERT_H__ /* Include assert.h only for internal use. */
+#include <assert.h> /* for assert() macro */
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Environment version might be used to avoid running with the old library */
+#define ASN1C_ENVIRONMENT_VERSION 920 /* Compile-time version */
+int get_asn1c_environment_version(void); /* Run-time version */
+
+#define CALLOC(nmemb, size) calloc(nmemb, size)
+#define MALLOC(size) malloc(size)
+#define REALLOC(oldptr, size) realloc(oldptr, size)
+#define FREEMEM(ptr) free(ptr)
+
+/*
+ * A macro for debugging the ASN.1 internals.
+ * You may enable or override it.
+ */
+#ifndef ASN_DEBUG /* If debugging code is not defined elsewhere... */
+#if EMIT_ASN_DEBUG == 1 /* And it was asked to emit this code... */
+#ifdef __GNUC__
+#define ASN_DEBUG(fmt, args...) do { \
+ fprintf(stderr, fmt, ##args); \
+ fprintf(stderr, " (%s:%d)\n", \
+ __FILE__, __LINE__); \
+ } while(0)
+#else /* !__GNUC__ */
+void ASN_DEBUG_f(const char *fmt, ...);
+#define ASN_DEBUG ASN_DEBUG_f
+#endif /* __GNUC__ */
+#else /* EMIT_ASN_DEBUG != 1 */
+static inline void ASN_DEBUG(const char *fmt, ...) { (void)fmt; }
+#endif /* EMIT_ASN_DEBUG */
+#endif /* ASN_DEBUG */
+
+/*
+ * Invoke the application-supplied callback and fail, if something is wrong.
+ */
+#define __ASN_E_cbc(buf, size) (cb((buf), (size), app_key) < 0)
+#define _ASN_E_CALLBACK(foo) do { \
+ if(foo) goto cb_failed; \
+ } while(0)
+#define _ASN_CALLBACK(buf, size) \
+ _ASN_E_CALLBACK(__ASN_E_cbc(buf, size))
+#define _ASN_CALLBACK2(buf1, size1, buf2, size2) \
+ _ASN_E_CALLBACK(__ASN_E_cbc(buf1, size1) || __ASN_E_cbc(buf2, size2))
+#define _ASN_CALLBACK3(buf1, size1, buf2, size2, buf3, size3) \
+ _ASN_E_CALLBACK(__ASN_E_cbc(buf1, size1) \
+ || __ASN_E_cbc(buf2, size2) \
+ || __ASN_E_cbc(buf3, size3))
+
+#define _i_ASN_TEXT_INDENT(nl, level) do { \
+ int __level = (level); \
+ int __nl = ((nl) != 0); \
+ int __i; \
+ if(__nl) _ASN_CALLBACK("\n", 1); \
+ for(__i = 0; __i < __level; __i++) \
+ _ASN_CALLBACK(" ", 4); \
+ er.encoded += __nl + 4 * __level; \
+} while(0)
+
+#define _i_INDENT(nl) do { \
+ int __i; \
+ if((nl) && cb("\n", 1, app_key) < 0) return -1; \
+ for(__i = 0; __i < ilevel; __i++) \
+ if(cb(" ", 4, app_key) < 0) return -1; \
+} while(0)
+
+/*
+ * Check stack against overflow, if limit is set.
+ */
+#define _ASN_DEFAULT_STACK_MAX (30000)
+static inline int
+_ASN_STACK_OVERFLOW_CHECK(asn_codec_ctx_t *ctx) {
+ if(ctx && ctx->max_stack_size) {
+
+ /* ctx MUST be allocated on the stack */
+ ptrdiff_t usedstack = ((char *)ctx - (char *)&ctx);
+ if(usedstack > 0) usedstack = -usedstack; /* grows up! */
+
+ /* double negative required to avoid int wrap-around */
+ if(usedstack < -(ptrdiff_t)ctx->max_stack_size) {
+ ASN_DEBUG("Stack limit %ld reached",
+ (long)ctx->max_stack_size);
+ return -1;
+ }
+ }
+ return 0;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ASN_INTERNAL_H_ */
--- /dev/null
+/*-
+ * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+/*
+ * Miscellaneous system-dependent types.
+ */
+#ifndef _ASN_SYSTEM_H_
+#define _ASN_SYSTEM_H_
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h> /* For snprintf(3) */
+#include <stdlib.h> /* For *alloc(3) */
+#include <string.h> /* For memcpy(3) */
+#include <sys/types.h> /* For size_t */
+#include <stdarg.h> /* For va_start */
+#include <stddef.h> /* for offsetof and ptrdiff_t */
+
+#ifdef WIN32
+
+#include <malloc.h>
+#include <stdint.h>
+#define snprintf _snprintf
+#define vsnprintf _vsnprintf
+
+#ifdef _MSC_VER /* MSVS.Net */
+#ifndef __cplusplus
+#define inline __inline
+#endif
+#define ssize_t SSIZE_T
+typedef char int8_t;
+typedef short int16_t;
+typedef int int32_t;
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned int uint32_t;
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <float.h>
+#define isnan _isnan
+#define finite _finite
+#define copysign _copysign
+#define ilogb _logb
+#endif /* _MSC_VER */
+
+#else /* !WIN32 */
+
+#if defined(__vxworks)
+#include <types/vxTypes.h>
+#else /* !defined(__vxworks) */
+
+#include <inttypes.h> /* C99 specifies this file */
+/*
+ * 1. Earlier FreeBSD version didn't have <stdint.h>,
+ * but <inttypes.h> was present.
+ * 2. Sun Solaris requires <alloca.h> for alloca(3),
+ * but does not have <stdint.h>.
+ */
+#if (!defined(__FreeBSD__) || !defined(_SYS_INTTYPES_H_))
+#if defined(sun)
+#include <alloca.h> /* For alloca(3) */
+#include <ieeefp.h> /* for finite(3) */
+#elif defined(__hpux)
+#ifdef __GNUC__
+#include <alloca.h> /* For alloca(3) */
+#else /* !__GNUC__ */
+#define inline
+#endif /* __GNUC__ */
+#else
+#include <stdint.h> /* SUSv2+ and C99 specify this file, for uintXX_t */
+#endif /* defined(sun) */
+#endif
+
+#endif /* defined(__vxworks) */
+
+#endif /* WIN32 */
+
+#if __GNUC__ >= 3
+#ifndef GCC_PRINTFLIKE
+#define GCC_PRINTFLIKE(fmt,var) __attribute__((format(printf,fmt,var)))
+#endif
+#else
+#ifndef GCC_PRINTFLIKE
+#define GCC_PRINTFLIKE(fmt,var) /* nothing */
+#endif
+#endif
+
+#ifndef offsetof /* If not defined by <stddef.h> */
+#define offsetof(s, m) ((ptrdiff_t)&(((s *)0)->m) - (ptrdiff_t)((s *)0))
+#endif /* offsetof */
+
+#ifndef MIN /* Suitable for comparing primitive types (integers) */
+#if defined(__GNUC__)
+#define MIN(a,b) ({ __typeof a _a = a; __typeof b _b = b; \
+ ((_a)<(_b)?(_a):(_b)); })
+#else /* !__GNUC__ */
+#define MIN(a,b) ((a)<(b)?(a):(b)) /* Unsafe variant */
+#endif /* __GNUC__ */
+#endif /* MIN */
+
+#endif /* _ASN_SYSTEM_H_ */
--- /dev/null
+/*-
+ * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#ifndef _BER_DECODER_H_
+#define _BER_DECODER_H_
+
+#include <asn_application.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct asn_TYPE_descriptor_s; /* Forward declaration */
+struct asn_codec_ctx_s; /* Forward declaration */
+
+/*
+ * The BER decoder of any type.
+ * This function may be invoked directly from the application.
+ */
+asn_dec_rval_t ber_decode(struct asn_codec_ctx_s *opt_codec_ctx,
+ struct asn_TYPE_descriptor_s *type_descriptor,
+ void **struct_ptr, /* Pointer to a target structure's pointer */
+ const void *buffer, /* Data to be decoded */
+ size_t size /* Size of that buffer */
+ );
+
+/*
+ * Type of generic function which decodes the byte stream into the structure.
+ */
+typedef asn_dec_rval_t (ber_type_decoder_f)(
+ struct asn_codec_ctx_s *opt_codec_ctx,
+ struct asn_TYPE_descriptor_s *type_descriptor,
+ void **struct_ptr, const void *buf_ptr, size_t size,
+ int tag_mode);
+
+/*******************************
+ * INTERNALLY USEFUL FUNCTIONS *
+ *******************************/
+
+/*
+ * Check that all tags correspond to the type definition (as given in head).
+ * On return, last_length would contain either a non-negative length of the
+ * value part of the last TLV, or the negative number of expected
+ * "end of content" sequences. The number may only be negative if the
+ * head->last_tag_form is non-zero.
+ */
+asn_dec_rval_t ber_check_tags(
+ struct asn_codec_ctx_s *opt_codec_ctx, /* codec options */
+ struct asn_TYPE_descriptor_s *type_descriptor,
+ asn_struct_ctx_t *opt_ctx, /* saved decoding context */
+ const void *ptr, size_t size,
+ int tag_mode, /* {-1,0,1}: IMPLICIT, no, EXPLICIT */
+ int last_tag_form, /* {-1,0:1}: any, primitive, constr */
+ ber_tlv_len_t *last_length,
+ int *opt_tlv_form /* optional tag form */
+ );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _BER_DECODER_H_ */
--- /dev/null
+/*-
+ * Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#ifndef _BER_TLV_LENGTH_H_
+#define _BER_TLV_LENGTH_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef ssize_t ber_tlv_len_t;
+
+/*
+ * This function tries to fetch the length of the BER TLV value and place it
+ * in *len_r.
+ * RETURN VALUES:
+ * 0: More data expected than bufptr contains.
+ * -1: Fatal error deciphering length.
+ * >0: Number of bytes used from bufptr.
+ * On return with >0, len_r is constrained as -1..MAX, where -1 mean
+ * that the value is of indefinite length.
+ */
+ssize_t ber_fetch_length(int _is_constructed, const void *bufptr, size_t size,
+ ber_tlv_len_t *len_r);
+
+/*
+ * This function expects bufptr to be positioned over L in TLV.
+ * It returns number of bytes occupied by L and V together, suitable
+ * for skipping. The function properly handles indefinite length.
+ * RETURN VALUES:
+ * Standard {-1,0,>0} convention.
+ */
+ssize_t ber_skip_length(
+ struct asn_codec_ctx_s *opt_codec_ctx, /* optional context */
+ int _is_constructed, const void *bufptr, size_t size);
+
+/*
+ * This function serializes the length (L from TLV) in DER format.
+ * It always returns number of bytes necessary to represent the length,
+ * it is a caller's responsibility to check the return value
+ * against the supplied buffer's size.
+ */
+size_t der_tlv_length_serialize(ber_tlv_len_t len, void *bufptr, size_t size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _BER_TLV_LENGTH_H_ */
--- /dev/null
+/*-
+ * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#ifndef _BER_TLV_TAG_H_
+#define _BER_TLV_TAG_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum asn_tag_class {
+ ASN_TAG_CLASS_UNIVERSAL = 0, /* 0b00 */
+ ASN_TAG_CLASS_APPLICATION = 1, /* 0b01 */
+ ASN_TAG_CLASS_CONTEXT = 2, /* 0b10 */
+ ASN_TAG_CLASS_PRIVATE = 3 /* 0b11 */
+};
+typedef unsigned ber_tlv_tag_t; /* BER TAG from Tag-Length-Value */
+
+/*
+ * Tag class is encoded together with tag value for optimization purposes.
+ */
+#define BER_TAG_CLASS(tag) ((tag) & 0x3)
+#define BER_TAG_VALUE(tag) ((tag) >> 2)
+#define BER_TLV_CONSTRUCTED(tagptr) (((*(const uint8_t *)tagptr)&0x20)?1:0)
+
+#define BER_TAGS_EQUAL(tag1, tag2) ((tag1) == (tag2))
+
+/*
+ * Several functions for printing the TAG in the canonical form
+ * (i.e. "[PRIVATE 0]").
+ * Return values correspond to their libc counterparts (if any).
+ */
+ssize_t ber_tlv_tag_snprint(ber_tlv_tag_t tag, char *buf, size_t buflen);
+ssize_t ber_tlv_tag_fwrite(ber_tlv_tag_t tag, FILE *);
+char *ber_tlv_tag_string(ber_tlv_tag_t tag);
+
+
+/*
+ * This function tries to fetch the tag from the input stream.
+ * RETURN VALUES:
+ * 0: More data expected than bufptr contains.
+ * -1: Fatal error deciphering tag.
+ * >0: Number of bytes used from bufptr. tag_r will contain the tag.
+ */
+ssize_t ber_fetch_tag(const void *bufptr, size_t size, ber_tlv_tag_t *tag_r);
+
+/*
+ * This function serializes the tag (T from TLV) in BER format.
+ * It always returns number of bytes necessary to represent the tag,
+ * it is a caller's responsibility to check the return value
+ * against the supplied buffer's size.
+ */
+size_t ber_tlv_tag_serialize(ber_tlv_tag_t tag, void *bufptr, size_t size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _BER_TLV_TAG_H_ */
--- /dev/null
+/*-
+ * Copyright (c) 2003, 2004, 2005 Lev Walkin <vlm@lionet.info>.
+ * All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#ifndef _CONSTR_CHOICE_H_
+#define _CONSTR_CHOICE_H_
+
+#include <asn_application.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct asn_CHOICE_specifics_s {
+ /*
+ * Target structure description.
+ */
+ int struct_size; /* Size of the target structure. */
+ int ctx_offset; /* Offset of the asn_codec_ctx_t member */
+ int pres_offset; /* Identifier of the present member */
+ int pres_size; /* Size of the identifier (enum) */
+
+ /*
+ * Tags to members mapping table.
+ */
+ asn_TYPE_tag2member_t *tag2el;
+ int tag2el_count;
+
+ /* Canonical ordering of CHOICE elements, for PER */
+ int *canonical_order;
+
+ /*
+ * Extensions-related stuff.
+ */
+ int ext_start; /* First member of extensions, or -1 */
+} asn_CHOICE_specifics_t;
+
+/*
+ * A set specialized functions dealing with the CHOICE type.
+ */
+asn_struct_free_f CHOICE_free;
+asn_struct_print_f CHOICE_print;
+asn_constr_check_f CHOICE_constraint;
+ber_type_decoder_f CHOICE_decode_ber;
+der_type_encoder_f CHOICE_encode_der;
+xer_type_decoder_f CHOICE_decode_xer;
+xer_type_encoder_f CHOICE_encode_xer;
+per_type_decoder_f CHOICE_decode_uper;
+per_type_encoder_f CHOICE_encode_uper;
+asn_outmost_tag_f CHOICE_outmost_tag;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CONSTR_CHOICE_H_ */
--- /dev/null
+/*-
+ * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#ifndef _CONSTR_SEQUENCE_H_
+#define _CONSTR_SEQUENCE_H_
+
+#include <asn_application.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct asn_SEQUENCE_specifics_s {
+ /*
+ * Target structure description.
+ */
+ int struct_size; /* Size of the target structure. */
+ int ctx_offset; /* Offset of the asn_struct_ctx_t member */
+
+ /*
+ * Tags to members mapping table (sorted).
+ */
+ asn_TYPE_tag2member_t *tag2el;
+ int tag2el_count;
+
+ /*
+ * Optional members of the extensions root (roms) or additions (aoms).
+ * Meaningful for PER.
+ */
+ int *oms; /* Optional MemberS */
+ int roms_count; /* Root optional members count */
+ int aoms_count; /* Additions optional members count */
+
+ /*
+ * Description of an extensions group.
+ */
+ int ext_after; /* Extensions start after this member */
+ int ext_before; /* Extensions stop before this member */
+} asn_SEQUENCE_specifics_t;
+
+
+/*
+ * A set specialized functions dealing with the SEQUENCE type.
+ */
+asn_struct_free_f SEQUENCE_free;
+asn_struct_print_f SEQUENCE_print;
+asn_constr_check_f SEQUENCE_constraint;
+ber_type_decoder_f SEQUENCE_decode_ber;
+der_type_encoder_f SEQUENCE_encode_der;
+xer_type_decoder_f SEQUENCE_decode_xer;
+xer_type_encoder_f SEQUENCE_encode_xer;
+per_type_decoder_f SEQUENCE_decode_uper;
+per_type_encoder_f SEQUENCE_encode_uper;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CONSTR_SEQUENCE_H_ */
--- /dev/null
+/*-
+ * Copyright (c) 2003, 2005 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#ifndef _CONSTR_SEQUENCE_OF_H_
+#define _CONSTR_SEQUENCE_OF_H_
+
+#include <asn_application.h>
+#include <constr_SET_OF.h> /* Implemented using SET OF */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * A set specialized functions dealing with the SEQUENCE OF type.
+ * Generally implemented using SET OF.
+ */
+#define SEQUENCE_OF_free SET_OF_free
+#define SEQUENCE_OF_print SET_OF_print
+#define SEQUENCE_OF_constraint SET_OF_constraint
+#define SEQUENCE_OF_decode_ber SET_OF_decode_ber
+#define SEQUENCE_OF_decode_xer SET_OF_decode_xer
+#define SEQUENCE_OF_decode_uper SET_OF_decode_uper
+der_type_encoder_f SEQUENCE_OF_encode_der;
+xer_type_encoder_f SEQUENCE_OF_encode_xer;
+per_type_encoder_f SEQUENCE_OF_encode_uper;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CONSTR_SET_OF_H_ */
--- /dev/null
+/*-
+ * Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#ifndef _CONSTR_SET_OF_H_
+#define _CONSTR_SET_OF_H_
+
+#include <asn_application.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct asn_SET_OF_specifics_s {
+ /*
+ * Target structure description.
+ */
+ int struct_size; /* Size of the target structure. */
+ int ctx_offset; /* Offset of the asn_struct_ctx_t member */
+
+ /* XER-specific stuff */
+ int as_XMLValueList; /* The member type must be encoded like this */
+} asn_SET_OF_specifics_t;
+
+/*
+ * A set specialized functions dealing with the SET OF type.
+ */
+asn_struct_free_f SET_OF_free;
+asn_struct_print_f SET_OF_print;
+asn_constr_check_f SET_OF_constraint;
+ber_type_decoder_f SET_OF_decode_ber;
+der_type_encoder_f SET_OF_encode_der;
+xer_type_decoder_f SET_OF_decode_xer;
+xer_type_encoder_f SET_OF_encode_xer;
+per_type_decoder_f SET_OF_decode_uper;
+per_type_encoder_f SET_OF_encode_uper;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CONSTR_SET_OF_H_ */
--- /dev/null
+/*-
+ * Copyright (c) 2003, 2004, 2005, 2006 Lev Walkin <vlm@lionet.info>.
+ * All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+/*
+ * This file contains the declaration structure called "ASN.1 Type Definition",
+ * which holds all information necessary for encoding and decoding routines.
+ * This structure even contains pointer to these encoding and decoding routines
+ * for each defined ASN.1 type.
+ */
+#ifndef _CONSTR_TYPE_H_
+#define _CONSTR_TYPE_H_
+
+#include <ber_tlv_length.h>
+#include <ber_tlv_tag.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct asn_TYPE_descriptor_s; /* Forward declaration */
+struct asn_TYPE_member_s; /* Forward declaration */
+
+/*
+ * This type provides the context information for various ASN.1 routines,
+ * primarily ones doing decoding. A member _asn_ctx of this type must be
+ * included into certain target language's structures, such as compound types.
+ */
+typedef struct asn_struct_ctx_s {
+ short phase; /* Decoding phase */
+ short step; /* Elementary step of a phase */
+ int context; /* Other context information */
+ void *ptr; /* Decoder-specific stuff (stack elements) */
+ ber_tlv_len_t left; /* Number of bytes left, -1 for indefinite */
+} asn_struct_ctx_t;
+
+#include <ber_decoder.h> /* Basic Encoding Rules decoder */
+#include <der_encoder.h> /* Distinguished Encoding Rules encoder */
+#include <xer_decoder.h> /* Decoder of XER (XML, text) */
+#include <xer_encoder.h> /* Encoder into XER (XML, text) */
+#include <per_decoder.h> /* Packet Encoding Rules decoder */
+#include <per_encoder.h> /* Packet Encoding Rules encoder */
+#include <constraints.h> /* Subtype constraints support */
+
+/*
+ * Free the structure according to its specification.
+ * If (free_contents_only) is set, the wrapper structure itself (struct_ptr)
+ * will not be freed. (It may be useful in case the structure is allocated
+ * statically or arranged on the stack, yet its elements are allocated
+ * dynamically.)
+ */
+typedef void (asn_struct_free_f)(
+ struct asn_TYPE_descriptor_s *type_descriptor,
+ void *struct_ptr, int free_contents_only);
+#define ASN_STRUCT_FREE(asn_DEF, ptr) (asn_DEF).free_struct(&(asn_DEF),ptr,0)
+#define ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF, ptr) \
+ (asn_DEF).free_struct(&(asn_DEF),ptr,1)
+
+/*
+ * Print the structure according to its specification.
+ */
+typedef int (asn_struct_print_f)(
+ struct asn_TYPE_descriptor_s *type_descriptor,
+ const void *struct_ptr,
+ int level, /* Indentation level */
+ asn_app_consume_bytes_f *callback, void *app_key);
+
+/*
+ * Return the outmost tag of the type.
+ * If the type is untagged CHOICE, the dynamic operation is performed.
+ * NOTE: This function pointer type is only useful internally.
+ * Do not use it in your application.
+ */
+typedef ber_tlv_tag_t (asn_outmost_tag_f)(
+ struct asn_TYPE_descriptor_s *type_descriptor,
+ const void *struct_ptr, int tag_mode, ber_tlv_tag_t tag);
+/* The instance of the above function type; used internally. */
+asn_outmost_tag_f asn_TYPE_outmost_tag;
+
+\f
+/*
+ * The definitive description of the destination language's structure.
+ */
+typedef struct asn_TYPE_descriptor_s {
+ char *name; /* A name of the ASN.1 type. "" in some cases. */
+ char *xml_tag; /* Name used in XML tag */
+
+ /*
+ * Generalized functions for dealing with the specific type.
+ * May be directly invoked by applications.
+ */
+ asn_struct_free_f *free_struct; /* Free the structure */
+ asn_struct_print_f *print_struct; /* Human readable output */
+ asn_constr_check_f *check_constraints; /* Constraints validator */
+ ber_type_decoder_f *ber_decoder; /* Generic BER decoder */
+ der_type_encoder_f *der_encoder; /* Canonical DER encoder */
+ xer_type_decoder_f *xer_decoder; /* Generic XER decoder */
+ xer_type_encoder_f *xer_encoder; /* [Canonical] XER encoder */
+ per_type_decoder_f *uper_decoder; /* Unaligned PER decoder */
+ per_type_encoder_f *uper_encoder; /* Unaligned PER encoder */
+
+ /***********************************************************************
+ * Internally useful members. Not to be used by applications directly. *
+ **********************************************************************/
+
+ /*
+ * Tags that are expected to occur.
+ */
+ asn_outmost_tag_f *outmost_tag; /* <optional, internal> */
+ ber_tlv_tag_t *tags; /* Effective tags sequence for this type */
+ int tags_count; /* Number of tags which are expected */
+ ber_tlv_tag_t *all_tags;/* Every tag for BER/containment */
+ int all_tags_count; /* Number of tags */
+
+ asn_per_constraints_t *per_constraints; /* PER compiled constraints */
+
+ /*
+ * An ASN.1 production type members (members of SEQUENCE, SET, CHOICE).
+ */
+ struct asn_TYPE_member_s *elements;
+ int elements_count;
+
+ /*
+ * Additional information describing the type, used by appropriate
+ * functions above.
+ */
+ void *specifics;
+} asn_TYPE_descriptor_t;
+
+/*
+ * This type describes an element of the constructed type,
+ * i.e. SEQUENCE, SET, CHOICE, etc.
+ */
+ enum asn_TYPE_flags_e {
+ ATF_NOFLAGS,
+ ATF_POINTER = 0x01, /* Represented by the pointer */
+ ATF_OPEN_TYPE = 0x02 /* ANY type, without meaningful tag */
+ };
+typedef struct asn_TYPE_member_s {
+ enum asn_TYPE_flags_e flags; /* Element's presentation flags */
+ int optional; /* Following optional members, including current */
+ int memb_offset; /* Offset of the element */
+ ber_tlv_tag_t tag; /* Outmost (most immediate) tag */
+ int tag_mode; /* IMPLICIT/no/EXPLICIT tag at current level */
+ asn_TYPE_descriptor_t *type; /* Member type descriptor */
+ asn_constr_check_f *memb_constraints; /* Constraints validator */
+ asn_per_constraints_t *per_constraints; /* PER compiled constraints */
+ int (*default_value)(int setval, void **sptr); /* DEFAULT <value> */
+ char *name; /* ASN.1 identifier of the element */
+} asn_TYPE_member_t;
+
+/*
+ * BER tag to element number mapping.
+ */
+typedef struct asn_TYPE_tag2member_s {
+ ber_tlv_tag_t el_tag; /* Outmost tag of the member */
+ int el_no; /* Index of the associated member, base 0 */
+ int toff_first; /* First occurence of the el_tag, relative */
+ int toff_last; /* Last occurence of the el_tag, relatvie */
+} asn_TYPE_tag2member_t;
+
+/*
+ * This function is a wrapper around (td)->print_struct, which prints out
+ * the contents of the target language's structure (struct_ptr) into the
+ * file pointer (stream) in human readable form.
+ * RETURN VALUES:
+ * 0: The structure is printed.
+ * -1: Problem dumping the structure.
+ * (See also xer_fprint() in xer_encoder.h)
+ */
+int asn_fprint(FILE *stream, /* Destination stream descriptor */
+ asn_TYPE_descriptor_t *td, /* ASN.1 type descriptor */
+ const void *struct_ptr); /* Structure to be printed */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CONSTR_TYPE_H_ */
--- /dev/null
+/*-
+ * Copyright (c) 2004, 2006 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#ifndef _ASN1_CONSTRAINTS_VALIDATOR_H_
+#define _ASN1_CONSTRAINTS_VALIDATOR_H_
+
+#include <asn_system.h> /* Platform-dependent types */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct asn_TYPE_descriptor_s; /* Forward declaration */
+
+/*
+ * Validate the structure according to the ASN.1 constraints.
+ * If errbuf and errlen are given, they shall be pointing to the appropriate
+ * buffer space and its length before calling this function. Alternatively,
+ * they could be passed as NULL's. If constraints validation fails,
+ * errlen will contain the actual number of bytes taken from the errbuf
+ * to encode an error message (properly 0-terminated).
+ *
+ * RETURN VALUES:
+ * This function returns 0 in case all ASN.1 constraints are met
+ * and -1 if one or more constraints were failed.
+ */
+int
+asn_check_constraints(struct asn_TYPE_descriptor_s *type_descriptor,
+ const void *struct_ptr, /* Target language's structure */
+ char *errbuf, /* Returned error description */
+ size_t *errlen /* Length of the error description */
+ );
+
+
+/*
+ * Generic type for constraint checking callback,
+ * associated with every type descriptor.
+ */
+typedef int (asn_constr_check_f)(
+ struct asn_TYPE_descriptor_s *type_descriptor,
+ const void *struct_ptr,
+ asn_app_constraint_failed_f *optional_callback, /* Log the error */
+ void *optional_app_key /* Opaque key passed to a callback */
+ );
+
+/*******************************
+ * INTERNALLY USEFUL FUNCTIONS *
+ *******************************/
+
+asn_constr_check_f asn_generic_no_constraint; /* No constraint whatsoever */
+asn_constr_check_f asn_generic_unknown_constraint; /* Not fully supported */
+
+/*
+ * Invoke the callback with a complete error message.
+ */
+#define _ASN_CTFAIL if(ctfailcb) ctfailcb
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ASN1_CONSTRAINTS_VALIDATOR_H_ */
--- /dev/null
+/*-
+ * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#ifndef _DER_ENCODER_H_
+#define _DER_ENCODER_H_
+
+#include <asn_application.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct asn_TYPE_descriptor_s; /* Forward declaration */
+
+/*
+ * The DER encoder of any type. May be invoked by the application.
+ */
+asn_enc_rval_t der_encode(struct asn_TYPE_descriptor_s *type_descriptor,
+ void *struct_ptr, /* Structure to be encoded */
+ asn_app_consume_bytes_f *consume_bytes_cb,
+ void *app_key /* Arbitrary callback argument */
+ );
+
+/* A variant of der_encode() which encodes data into the pre-allocated buffer */
+asn_enc_rval_t der_encode_to_buffer(
+ struct asn_TYPE_descriptor_s *type_descriptor,
+ void *struct_ptr, /* Structure to be encoded */
+ void *buffer, /* Pre-allocated buffer */
+ size_t buffer_size /* Initial buffer size (maximum) */
+ );
+
+/*
+ * Type of the generic DER encoder.
+ */
+typedef asn_enc_rval_t (der_type_encoder_f)(
+ struct asn_TYPE_descriptor_s *type_descriptor,
+ void *struct_ptr, /* Structure to be encoded */
+ int tag_mode, /* {-1,0,1}: IMPLICIT, no, EXPLICIT */
+ ber_tlv_tag_t tag,
+ asn_app_consume_bytes_f *consume_bytes_cb, /* Callback */
+ void *app_key /* Arbitrary callback argument */
+ );
+
+
+/*******************************
+ * INTERNALLY USEFUL FUNCTIONS *
+ *******************************/
+
+/*
+ * Write out leading TL[v] sequence according to the type definition.
+ */
+ssize_t der_write_tags(
+ struct asn_TYPE_descriptor_s *type_descriptor,
+ size_t struct_length,
+ int tag_mode, /* {-1,0,1}: IMPLICIT, no, EXPLICIT */
+ int last_tag_form, /* {0,!0}: prim, constructed */
+ ber_tlv_tag_t tag,
+ asn_app_consume_bytes_f *consume_bytes_cb,
+ void *app_key
+ );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _DER_ENCODER_H_ */
--- /dev/null
+/*-
+ * Copyright (c) 2005 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#ifndef _PER_DECODER_H_
+#define _PER_DECODER_H_
+
+#include <asn_application.h>
+#include <per_support.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct asn_TYPE_descriptor_s; /* Forward declaration */
+
+/*
+ * Unaligned PER decoder of any ASN.1 type. May be invoked by the application.
+ */
+asn_dec_rval_t uper_decode(struct asn_codec_ctx_s *opt_codec_ctx,
+ struct asn_TYPE_descriptor_s *type_descriptor, /* Type to decode */
+ void **struct_ptr, /* Pointer to a target structure's pointer */
+ const void *buffer, /* Data to be decoded */
+ size_t size, /* Size of data buffer */
+ int skip_bits, /* Number of unused leading bits, 0..7 */
+ int unused_bits /* Number of unused tailing bits, 0..7 */
+ );
+
+
+/*
+ * Type of the type-specific PER decoder function.
+ */
+typedef asn_dec_rval_t (per_type_decoder_f)(asn_codec_ctx_t *opt_codec_ctx,
+ struct asn_TYPE_descriptor_s *type_descriptor,
+ asn_per_constraints_t *constraints,
+ void **struct_ptr,
+ asn_per_data_t *per_data
+ );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _PER_DECODER_H_ */
--- /dev/null
+/*-
+ * Copyright (c) 2006 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#ifndef _PER_ENCODER_H_
+#define _PER_ENCODER_H_
+
+#include <asn_application.h>
+#include <per_support.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct asn_TYPE_descriptor_s; /* Forward declaration */
+
+/*
+ * Unaligned PER encoder of any ASN.1 type. May be invoked by the application.
+ */
+asn_enc_rval_t uper_encode(struct asn_TYPE_descriptor_s *type_descriptor,
+ void *struct_ptr, /* Structure to be encoded */
+ asn_app_consume_bytes_f *consume_bytes_cb, /* Data collector */
+ void *app_key /* Arbitrary callback argument */
+);
+
+/* A variant of uper_encode() which encodes data into the existing buffer */
+asn_enc_rval_t uper_encode_to_buffer(
+ struct asn_TYPE_descriptor_s *type_descriptor,
+ void *struct_ptr, /* Structure to be encoded */
+ void *buffer, /* Pre-allocated buffer */
+ size_t buffer_size /* Initial buffer size (max) */
+);
+
+
+/*
+ * Type of the generic PER encoder function.
+ */
+typedef asn_enc_rval_t (per_type_encoder_f)(
+ struct asn_TYPE_descriptor_s *type_descriptor,
+ asn_per_constraints_t *constraints,
+ void *struct_ptr,
+ asn_per_outp_t *per_output
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _PER_ENCODER_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2005, 2006 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#ifndef _PER_SUPPORT_H_
+#define _PER_SUPPORT_H_
+
+#include <asn_system.h> /* Platform-specific types */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Pre-computed PER constraints.
+ */
+typedef struct asn_per_constraint_s {
+ enum asn_per_constraint_flags {
+ APC_UNCONSTRAINED = 0x0, /* No PER visible constraints */
+ APC_SEMI_CONSTRAINED = 0x1, /* Constrained at "lb" */
+ APC_CONSTRAINED = 0x2, /* Fully constrained */
+ APC_EXTENSIBLE = 0x4 /* May have extension */
+ } flags;
+ int range_bits; /* Full number of bits in the range */
+ int effective_bits; /* Effective bits */
+ long lower_bound; /* "lb" value */
+ long upper_bound; /* "ub" value */
+} asn_per_constraint_t;
+typedef struct asn_per_constraints_s {
+ asn_per_constraint_t value;
+ asn_per_constraint_t size;
+} asn_per_constraints_t;
+
+/*
+ * This structure describes a position inside an incoming PER bit stream.
+ */
+typedef struct asn_per_data_s {
+ const uint8_t *buffer; /* Pointer to the octet stream */
+ size_t nboff; /* Bit offset to the meaningful bit */
+ size_t nbits; /* Number of bits in the stream */
+} asn_per_data_t;
+
+/*
+ * Extract a small number of bits (<= 31) from the specified PER data pointer.
+ * This function returns -1 if the specified number of bits could not be
+ * extracted due to EOD or other conditions.
+ */
+int32_t per_get_few_bits(asn_per_data_t *per_data, int get_nbits);
+
+/*
+ * Extract a large number of bits from the specified PER data pointer.
+ * This function returns -1 if the specified number of bits could not be
+ * extracted due to EOD or other conditions.
+ */
+int per_get_many_bits(asn_per_data_t *pd, uint8_t *dst, int right_align,
+ int get_nbits);
+
+/*
+ * Get the length "n" from the Unaligned PER stream.
+ */
+ssize_t uper_get_length(asn_per_data_t *pd,
+ int effective_bound_bits,
+ int *repeat);
+
+/*
+ * Get the normally small non-negative whole number.
+ */
+ssize_t uper_get_nsnnwn(asn_per_data_t *pd);
+
+/*
+ * This structure supports forming PER output.
+ */
+typedef struct asn_per_outp_s {
+ uint8_t *buffer; /* Pointer into the (tmpspace) */
+ size_t nboff; /* Bit offset to the meaningful bit */
+ size_t nbits; /* Number of bits left in (tmpspace) */
+ uint8_t tmpspace[32]; /* Preliminary storage to hold data */
+ int (*outper)(const void *data, size_t size, void *op_key);
+ void *op_key; /* Key for (outper) data callback */
+ size_t flushed_bytes; /* Bytes already flushed through (outper) */
+} asn_per_outp_t;
+
+/* Output a small number of bits (<= 31) */
+int per_put_few_bits(asn_per_outp_t *per_data, uint32_t bits, int obits);
+
+/* Output a large number of bits */
+int per_put_many_bits(asn_per_outp_t *po, const uint8_t *src, int put_nbits);
+
+/*
+ * Put the length "n" to the Unaligned PER stream.
+ * This function returns the number of units which may be flushed
+ * in the next units saving iteration.
+ */
+ssize_t uper_put_length(asn_per_outp_t *po, size_t whole_length);
+
+/*
+ * Put the normally small non-negative whole number.
+ */
+int uper_put_nsnnwn(asn_per_outp_t *po, int n);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _PER_SUPPORT_H_ */
--- /dev/null
+/*-
+ * Copyright (c) 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#ifndef _XER_DECODER_H_
+#define _XER_DECODER_H_
+
+#include <asn_application.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct asn_TYPE_descriptor_s; /* Forward declaration */
+
+/*
+ * The XER decoder of any ASN.1 type. May be invoked by the application.
+ */
+asn_dec_rval_t xer_decode(struct asn_codec_ctx_s *opt_codec_ctx,
+ struct asn_TYPE_descriptor_s *type_descriptor,
+ void **struct_ptr, /* Pointer to a target structure's pointer */
+ const void *buffer, /* Data to be decoded */
+ size_t size /* Size of data buffer */
+ );
+
+/*
+ * Type of the type-specific XER decoder function.
+ */
+typedef asn_dec_rval_t (xer_type_decoder_f)(asn_codec_ctx_t *opt_codec_ctx,
+ struct asn_TYPE_descriptor_s *type_descriptor,
+ void **struct_ptr,
+ const char *opt_mname, /* Member name */
+ const void *buf_ptr, size_t size
+ );
+
+/*******************************
+ * INTERNALLY USEFUL FUNCTIONS *
+ *******************************/
+
+/*
+ * Generalized function for decoding the primitive values.
+ * Used by more specialized functions, such as OCTET_STRING_decode_xer_utf8
+ * and others. This function should not be used by applications, as its API
+ * is subject to changes.
+ */
+asn_dec_rval_t xer_decode_general(asn_codec_ctx_t *opt_codec_ctx,
+ asn_struct_ctx_t *ctx, /* Type decoder context */
+ void *struct_key, /* Treated as opaque pointer */
+ const char *xml_tag, /* Expected XML tag name */
+ const void *buf_ptr, size_t size,
+ int (*opt_unexpected_tag_decoder)
+ (void *struct_key, const void *chunk_buf, size_t chunk_size),
+ ssize_t (*body_receiver)
+ (void *struct_key, const void *chunk_buf, size_t chunk_size,
+ int have_more)
+ );
+
+
+/*
+ * Fetch the next XER (XML) token from the stream.
+ * The function returns the number of bytes occupied by the chunk type,
+ * returned in the _ch_type. The _ch_type is only set (and valid) when
+ * the return value is greater than 0.
+ */
+ typedef enum pxer_chunk_type {
+ PXER_TAG, /* Complete XER tag */
+ PXER_TEXT, /* Plain text between XER tags */
+ PXER_COMMENT /* A comment, may be part of */
+ } pxer_chunk_type_e;
+ssize_t xer_next_token(int *stateContext,
+ const void *buffer, size_t size, pxer_chunk_type_e *_ch_type);
+
+/*
+ * This function checks the buffer against the tag name is expected to occur.
+ */
+ typedef enum xer_check_tag {
+ XCT_BROKEN = 0, /* The tag is broken */
+ XCT_OPENING = 1, /* This is the <opening> tag */
+ XCT_CLOSING = 2, /* This is the </closing> tag */
+ XCT_BOTH = 3, /* This is the <modified/> tag */
+ XCT__UNK__MASK = 4, /* Mask of everything unexpected */
+ XCT_UNKNOWN_OP = 5, /* Unexpected <opening> tag */
+ XCT_UNKNOWN_CL = 6, /* Unexpected </closing> tag */
+ XCT_UNKNOWN_BO = 7 /* Unexpected <modified/> tag */
+ } xer_check_tag_e;
+xer_check_tag_e xer_check_tag(const void *buf_ptr, int size,
+ const char *need_tag);
+
+/*
+ * Check whether this buffer consists of entirely XER whitespace characters.
+ * RETURN VALUES:
+ * 1: Whitespace or empty string
+ * 0: Non-whitespace
+ */
+int xer_is_whitespace(const void *chunk_buf, size_t chunk_size);
+
+/*
+ * Skip the series of anticipated extensions.
+ */
+int xer_skip_unknown(xer_check_tag_e tcv, ber_tlv_len_t *depth);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _XER_DECODER_H_ */
--- /dev/null
+/*-
+ * Copyright (c) 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#ifndef _XER_ENCODER_H_
+#define _XER_ENCODER_H_
+
+#include <asn_application.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct asn_TYPE_descriptor_s; /* Forward declaration */
+
+/* Flags used by the xer_encode() and (*xer_type_encoder_f), defined below */
+enum xer_encoder_flags_e {
+ /* Mode of encoding */
+ XER_F_BASIC = 0x01, /* BASIC-XER (pretty-printing) */
+ XER_F_CANONICAL = 0x02 /* Canonical XER (strict rules) */
+};
+
+/*
+ * The XER encoder of any type. May be invoked by the application.
+ */
+asn_enc_rval_t xer_encode(struct asn_TYPE_descriptor_s *type_descriptor,
+ void *struct_ptr, /* Structure to be encoded */
+ enum xer_encoder_flags_e xer_flags,
+ asn_app_consume_bytes_f *consume_bytes_cb,
+ void *app_key /* Arbitrary callback argument */
+ );
+
+/*
+ * The variant of the above function which dumps the BASIC-XER (XER_F_BASIC)
+ * output into the chosen file pointer.
+ * RETURN VALUES:
+ * 0: The structure is printed.
+ * -1: Problem printing the structure.
+ * WARNING: No sensible errno value is returned.
+ */
+int xer_fprint(FILE *stream, struct asn_TYPE_descriptor_s *td, void *sptr);
+
+/*
+ * Type of the generic XER encoder.
+ */
+typedef asn_enc_rval_t (xer_type_encoder_f)(
+ struct asn_TYPE_descriptor_s *type_descriptor,
+ void *struct_ptr, /* Structure to be encoded */
+ int ilevel, /* Level of indentation */
+ enum xer_encoder_flags_e xer_flags,
+ asn_app_consume_bytes_f *consume_bytes_cb, /* Callback */
+ void *app_key /* Arbitrary callback argument */
+ );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _XER_ENCODER_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2003, 2004 X/IO Labs, xiolabs.com.
+ * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#ifndef _XER_SUPPORT_H_
+#define _XER_SUPPORT_H_
+
+#include <asn_system.h> /* Platform-specific types */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Types of data transferred to the application.
+ */
+typedef enum {
+ PXML_TEXT, /* Plain text between XML tags. */
+ PXML_TAG, /* A tag, starting with '<'. */
+ PXML_COMMENT, /* An XML comment, including "<!--" and "-->". */
+ /*
+ * The following chunk types are reported if the chunk
+ * terminates the specified XML element.
+ */
+ PXML_TAG_END, /* Tag ended */
+ PXML_COMMENT_END /* Comment ended */
+} pxml_chunk_type_e;
+
+/*
+ * Callback function that is called by the parser when parsed data is
+ * available. The _opaque is the pointer to a field containing opaque user
+ * data specified in pxml_create() call. The chunk type is _type and the text
+ * data is the piece of buffer identified by _bufid (as supplied to
+ * pxml_feed() call) starting at offset _offset and of _size bytes size.
+ * The chunk is NOT '\0'-terminated.
+ */
+typedef int (pxml_callback_f)(pxml_chunk_type_e _type,
+ const void *_chunk_data, size_t _chunk_size, void *_key);
+
+/*
+ * Parse the given buffer as it were a chunk of XML data.
+ * Invoke the specified callback each time the meaninful data is found.
+ * This function returns number of bytes consumed from the bufer.
+ * It will always be lesser than or equal to the specified _size.
+ * The next invocation of this function must account the difference.
+ */
+ssize_t pxml_parse(int *_stateContext, const void *_buf, size_t _size,
+ pxml_callback_f *cb, void *_key);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _XER_SUPPORT_H_ */
--- /dev/null
+#include <asn_application.h>
+#include <asn_internal.h>
+#include <per_decoder.h>
+
+asn_dec_rval_t
+uper_decode(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, void **sptr, const void *buffer, size_t size, int skip_bits, int unused_bits) {
+ asn_codec_ctx_t s_codec_ctx;
+ asn_dec_rval_t rval;
+ asn_per_data_t pd;
+
+ if(skip_bits < 0 || skip_bits > 7
+ || unused_bits < 0 || unused_bits > 7
+ || (unused_bits > 0 && !size))
+ _ASN_DECODE_FAILED;
+
+ /*
+ * Stack checker requires that the codec context
+ * must be allocated on the stack.
+ */
+ if(opt_codec_ctx) {
+ if(opt_codec_ctx->max_stack_size) {
+ s_codec_ctx = *opt_codec_ctx;
+ opt_codec_ctx = &s_codec_ctx;
+ }
+ } else {
+ /* If context is not given, be security-conscious anyway */
+ memset(&s_codec_ctx, 0, sizeof(s_codec_ctx));
+ s_codec_ctx.max_stack_size = _ASN_DEFAULT_STACK_MAX;
+ opt_codec_ctx = &s_codec_ctx;
+ }
+
+ /* Fill in the position indicator */
+ pd.buffer = (const uint8_t *)buffer;
+ pd.nboff = skip_bits;
+ pd.nbits = 8 * size - unused_bits; /* 8 is CHAR_BIT from <limits.h> */
+ if(pd.nboff > pd.nbits)
+ _ASN_DECODE_FAILED;
+
+ /*
+ * Invoke type-specific decoder.
+ */
+ if(!td->uper_decoder)
+ _ASN_DECODE_FAILED; /* PER is not compiled in */
+ rval = td->uper_decoder(opt_codec_ctx, td, 0, sptr, &pd);
+ if(rval.code == RC_OK) {
+ /* Return the number of consumed bits */
+ rval.consumed = ((pd.buffer - (const uint8_t *)buffer) << 3)
+ + pd.nboff - skip_bits;
+ } else {
+ /* PER codec is not a restartable */
+ rval.consumed = 0;
+ }
+ return rval;
+}
+
--- /dev/null
+#include <asn_application.h>
+#include <asn_internal.h>
+#include <per_encoder.h>
+
+/* Flush partially filled buffer */
+static int _uper_encode_flush_outp(asn_per_outp_t *po);
+
+asn_enc_rval_t
+uper_encode(asn_TYPE_descriptor_t *td, void *sptr, asn_app_consume_bytes_f *cb, void *app_key) {
+ asn_per_outp_t po;
+ asn_enc_rval_t er;
+
+ /*
+ * Invoke type-specific encoder.
+ */
+ if(!td || !td->uper_encoder)
+ _ASN_ENCODE_FAILED; /* PER is not compiled in */
+
+ po.buffer = po.tmpspace;
+ po.nboff = 0;
+ po.nbits = 8 * sizeof(po.tmpspace);
+ po.outper = cb;
+ po.op_key = app_key;
+ po.flushed_bytes = 0;
+
+ er = td->uper_encoder(td, 0, sptr, &po);
+ if(er.encoded != -1) {
+ size_t bits_to_flush;
+
+ bits_to_flush = ((po.buffer - po.tmpspace) << 3) + po.nboff;
+
+ /* Set number of bits encoded to a firm value */
+ er.encoded = (po.flushed_bytes << 3) + bits_to_flush;
+
+ if(_uper_encode_flush_outp(&po))
+ _ASN_ENCODE_FAILED;
+ }
+
+ return er;
+}
+
+/*
+ * Argument type and callback necessary for uper_encode_to_buffer().
+ */
+typedef struct enc_to_buf_arg {
+ void *buffer;
+ size_t left;
+} enc_to_buf_arg;
+static int encode_to_buffer_cb(const void *buffer, size_t size, void *key) {
+ enc_to_buf_arg *arg = (enc_to_buf_arg *)key;
+
+ if(arg->left < size)
+ return -1; /* Data exceeds the available buffer size */
+
+ memcpy(arg->buffer, buffer, size);
+ arg->buffer = ((char *)arg->buffer) + size;
+ arg->left -= size;
+
+ return 0;
+}
+
+asn_enc_rval_t
+uper_encode_to_buffer(asn_TYPE_descriptor_t *td, void *sptr, void *buffer, size_t buffer_size) {
+ enc_to_buf_arg key;
+
+ /*
+ * Invoke type-specific encoder.
+ */
+ if(!td || !td->uper_encoder)
+ _ASN_ENCODE_FAILED; /* PER is not compiled in */
+
+ key.buffer = buffer;
+ key.left = buffer_size;
+
+ ASN_DEBUG("Encoding \"%s\" using UNALIGNED PER", td->name);
+
+ return uper_encode(td, sptr, encode_to_buffer_cb, &key);
+}
+
+static int
+_uper_encode_flush_outp(asn_per_outp_t *po) {
+ uint8_t *buf;
+
+ if(po->nboff == 0 && po->buffer == po->tmpspace)
+ return 0;
+
+ buf = po->buffer + (po->nboff >> 3);
+ /* Make sure we account for the last, partially filled */
+ if(po->nboff & 0x07) {
+ buf[0] &= 0xff << (8 - (po->nboff & 0x07));
+ buf++;
+ }
+
+ return po->outper(po->tmpspace, buf - po->tmpspace, po->op_key);
+}
--- /dev/null
+/*
+ * Copyright (c) 2005, 2006 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#include <asn_system.h>
+#include <asn_internal.h>
+#include <per_support.h>
+
+/*
+ * Extract a small number of bits (<= 31) from the specified PER data pointer.
+ */
+int32_t
+per_get_few_bits(asn_per_data_t *pd, int nbits) {
+ size_t off; /* Next after last bit offset */
+ uint32_t accum;
+ const uint8_t *buf;
+
+ if(nbits < 0 || pd->nboff + nbits > pd->nbits)
+ return -1;
+
+ ASN_DEBUG("[PER get %d bits from %p+%d bits]",
+ nbits, pd->buffer, pd->nboff);
+
+ /*
+ * Normalize position indicator.
+ */
+ if(pd->nboff >= 8) {
+ pd->buffer += (pd->nboff >> 3);
+ pd->nbits -= (pd->nboff & ~0x07);
+ pd->nboff &= 0x07;
+ }
+ off = (pd->nboff += nbits);
+ buf = pd->buffer;
+
+ /*
+ * Extract specified number of bits.
+ */
+ if(off <= 8)
+ accum = nbits ? (buf[0]) >> (8 - off) : 0;
+ else if(off <= 16)
+ accum = ((buf[0] << 8) + buf[1]) >> (16 - off);
+ else if(off <= 24)
+ accum = ((buf[0] << 16) + (buf[1] << 8) + buf[2]) >> (24 - off);
+ else if(off <= 31)
+ accum = ((buf[0] << 24) + (buf[1] << 16)
+ + (buf[2] << 8) + (buf[3])) >> (32 - off);
+ else if(nbits <= 31) {
+ asn_per_data_t tpd = *pd;
+ /* Here are we with our 31-bits limit plus 1..7 bits offset. */
+ tpd.nboff -= nbits;
+ accum = per_get_few_bits(&tpd, nbits - 24) << 24;
+ accum |= per_get_few_bits(&tpd, 24);
+ } else {
+ pd->nboff -= nbits; /* Oops, revert back */
+ return -1;
+ }
+
+ return (accum & (((uint32_t)1 << nbits) - 1));
+}
+
+/*
+ * Extract a large number of bits from the specified PER data pointer.
+ */
+int
+per_get_many_bits(asn_per_data_t *pd, uint8_t *dst, int alright, int nbits) {
+ int32_t value;
+
+ if(alright && (nbits & 7)) {
+ /* Perform right alignment of a first few bits */
+ value = per_get_few_bits(pd, nbits & 0x07);
+ if(value < 0) return -1;
+ *dst++ = value; /* value is already right-aligned */
+ nbits &= ~7;
+ }
+
+ while(nbits) {
+ if(nbits >= 24) {
+ value = per_get_few_bits(pd, 24);
+ if(value < 0) return -1;
+ *(dst++) = value >> 16;
+ *(dst++) = value >> 8;
+ *(dst++) = value;
+ nbits -= 24;
+ } else {
+ value = per_get_few_bits(pd, nbits);
+ if(value < 0) return -1;
+ if(nbits & 7) { /* implies left alignment */
+ value <<= 8 - (nbits & 7),
+ nbits += 8 - (nbits & 7);
+ if(nbits > 24)
+ *dst++ = value >> 24;
+ }
+ if(nbits > 16)
+ *dst++ = value >> 16;
+ if(nbits > 8)
+ *dst++ = value >> 8;
+ *dst++ = value;
+ break;
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * Get the length "n" from the stream.
+ */
+ssize_t
+uper_get_length(asn_per_data_t *pd, int ebits, int *repeat) {
+ ssize_t value;
+
+ *repeat = 0;
+
+ if(ebits >= 0) return per_get_few_bits(pd, ebits);
+
+ value = per_get_few_bits(pd, 8);
+ if(value < 0) return -1;
+ if((value & 128) == 0) /* #10.9.3.6 */
+ return (value & 0x7F);
+ if((value & 64) == 0) { /* #10.9.3.7 */
+ value = ((value & 63) << 8) | per_get_few_bits(pd, 8);
+ if(value < 0) return -1;
+ return value;
+ }
+ value &= 63; /* this is "m" from X.691, #10.9.3.8 */
+ if(value < 1 || value > 4)
+ return -1;
+ *repeat = 1;
+ return (16384 * value);
+}
+
+/*
+ * Get the normally small non-negative whole number.
+ * X.691, #10.6
+ */
+ssize_t
+uper_get_nsnnwn(asn_per_data_t *pd) {
+ ssize_t value;
+
+ value = per_get_few_bits(pd, 7);
+ if(value & 64) { /* implicit (value < 0) */
+ value &= 63;
+ value <<= 2;
+ value |= per_get_few_bits(pd, 2);
+ if(value & 128) /* implicit (value < 0) */
+ return -1;
+ if(value == 0)
+ return 0;
+ if(value >= 3)
+ return -1;
+ value = per_get_few_bits(pd, 8 * value);
+ return value;
+ }
+
+ return value;
+}
+
+/*
+ * Put the normally small non-negative whole number.
+ * X.691, #10.6
+ */
+int
+uper_put_nsnnwn(asn_per_outp_t *po, int n) {
+ int bytes;
+
+ if(n <= 63) {
+ if(n < 0) return -1;
+ return per_put_few_bits(po, n, 7);
+ }
+ if(n < 256)
+ bytes = 1;
+ else if(n < 65536)
+ bytes = 2;
+ else if(n < 256 * 65536)
+ bytes = 3;
+ else
+ return -1; /* This is not a "normally small" value */
+ if(per_put_few_bits(po, bytes, 8))
+ return -1;
+
+ return per_put_few_bits(po, n, 8 * bytes);
+}
+
+
+/*
+ * Put a small number of bits (<= 31).
+ */
+int
+per_put_few_bits(asn_per_outp_t *po, uint32_t bits, int obits) {
+ size_t off; /* Next after last bit offset */
+ size_t omsk; /* Existing last byte meaningful bits mask */
+ uint8_t *buf;
+
+ if(obits <= 0 || obits >= 32) return obits ? -1 : 0;
+
+ ASN_DEBUG("[PER put %d bits to %p+%d bits]",
+ obits, po->buffer, po->nboff);
+
+ /*
+ * Normalize position indicator.
+ */
+ if(po->nboff >= 8) {
+ po->buffer += (po->nboff >> 3);
+ po->nbits -= (po->nboff & ~0x07);
+ po->nboff &= 0x07;
+ }
+
+ /*
+ * Flush whole-bytes output, if necessary.
+ */
+ if(po->nboff + obits > po->nbits) {
+ int complete_bytes = (po->buffer - po->tmpspace);
+ if(po->outper(po->buffer, complete_bytes, po->op_key) < 0)
+ return -1;
+ if(po->nboff)
+ po->tmpspace[0] = po->buffer[0];
+ po->buffer = po->tmpspace;
+ po->nbits = 8 * sizeof(po->tmpspace);
+ po->flushed_bytes += complete_bytes;
+ }
+
+ /*
+ * Now, due to sizeof(tmpspace), we are guaranteed large enough space.
+ */
+ buf = po->buffer;
+ omsk = ~((1 << (8 - po->nboff)) - 1);
+ off = (po->nboff += obits);
+
+ /* Clear data of debris before meaningful bits */
+ bits &= (((uint32_t)1 << obits) - 1);
+
+ ASN_DEBUG("[PER out %d %u/%x (t=%d,o=%d) %x&%x=%x]", obits, bits, bits,
+ po->nboff - obits, off, buf[0], omsk&0xff, buf[0] & omsk);
+
+ if(off <= 8) /* Completely within 1 byte */
+ bits <<= (8 - off),
+ buf[0] = (buf[0] & omsk) | bits;
+ else if(off <= 16)
+ bits <<= (16 - off),
+ buf[0] = (buf[0] & omsk) | (bits >> 8),
+ buf[1] = bits;
+ else if(off <= 24)
+ bits <<= (24 - off),
+ buf[0] = (buf[0] & omsk) | (bits >> 16),
+ buf[1] = bits >> 8,
+ buf[2] = bits;
+ else if(off <= 31)
+ bits <<= (32 - off),
+ buf[0] = (buf[0] & omsk) | (bits >> 24),
+ buf[1] = bits >> 16,
+ buf[2] = bits >> 8,
+ buf[3] = bits;
+ else {
+ ASN_DEBUG("->[PER out split %d]", obits);
+ per_put_few_bits(po, bits >> 8, 24);
+ per_put_few_bits(po, bits, obits - 24);
+ ASN_DEBUG("<-[PER out split %d]", obits);
+ }
+
+ ASN_DEBUG("[PER out %u/%x => %02x buf+%d]",
+ bits, bits, buf[0], po->buffer - po->tmpspace);
+
+ return 0;
+}
+
+
+/*
+ * Output a large number of bits.
+ */
+int
+per_put_many_bits(asn_per_outp_t *po, const uint8_t *src, int nbits) {
+
+ while(nbits) {
+ uint32_t value;
+
+ if(nbits >= 24) {
+ value = (src[0] << 16) | (src[1] << 8) | src[2];
+ src += 3;
+ nbits -= 24;
+ if(per_put_few_bits(po, value, 24))
+ return -1;
+ } else {
+ value = src[0];
+ if(nbits > 8)
+ value = (value << 8) | src[1];
+ if(nbits > 16)
+ value = (value << 8) | src[2];
+ if(nbits & 0x07)
+ value >>= (8 - (nbits & 0x07));
+ if(per_put_few_bits(po, value, nbits))
+ return -1;
+ break;
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * Put the length "n" (or part of it) into the stream.
+ */
+ssize_t
+uper_put_length(asn_per_outp_t *po, size_t length) {
+
+ if(length <= 127) /* #10.9.3.6 */
+ return per_put_few_bits(po, length, 8)
+ ? -1 : (ssize_t)length;
+ else if(length < 16384) /* #10.9.3.7 */
+ return per_put_few_bits(po, length|0x8000, 16)
+ ? -1 : (ssize_t)length;
+
+ length >>= 14;
+ if(length > 4) length = 4;
+
+ return per_put_few_bits(po, 0xC0 | length, 8)
+ ? -1 : (ssize_t)(length << 14);
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2004, 2005 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#include <asn_application.h>
+#include <asn_internal.h>
+#include <xer_support.h> /* XER/XML parsing support */
+
+
+/*
+ * Decode the XER encoding of a given type.
+ */
+asn_dec_rval_t
+xer_decode(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ void **struct_ptr, const void *buffer, size_t size) {
+ asn_codec_ctx_t s_codec_ctx;
+
+ /*
+ * Stack checker requires that the codec context
+ * must be allocated on the stack.
+ */
+ if(opt_codec_ctx) {
+ if(opt_codec_ctx->max_stack_size) {
+ s_codec_ctx = *opt_codec_ctx;
+ opt_codec_ctx = &s_codec_ctx;
+ }
+ } else {
+ /* If context is not given, be security-conscious anyway */
+ memset(&s_codec_ctx, 0, sizeof(s_codec_ctx));
+ s_codec_ctx.max_stack_size = _ASN_DEFAULT_STACK_MAX;
+ opt_codec_ctx = &s_codec_ctx;
+ }
+
+ /*
+ * Invoke type-specific decoder.
+ */
+ return td->xer_decoder(opt_codec_ctx, td, struct_ptr, 0, buffer, size);
+}
+
+
+
+struct xer__cb_arg {
+ pxml_chunk_type_e chunk_type;
+ size_t chunk_size;
+ const void *chunk_buf;
+ int callback_not_invoked;
+};
+
+static int
+xer__token_cb(pxml_chunk_type_e type, const void *_chunk_data, size_t _chunk_size, void *key) {
+ struct xer__cb_arg *arg = (struct xer__cb_arg *)key;
+ arg->chunk_type = type;
+ arg->chunk_size = _chunk_size;
+ arg->chunk_buf = _chunk_data;
+ arg->callback_not_invoked = 0;
+ return -1; /* Terminate the XML parsing */
+}
+
+/*
+ * Fetch the next token from the XER/XML stream.
+ */
+ssize_t
+xer_next_token(int *stateContext, const void *buffer, size_t size, pxer_chunk_type_e *ch_type) {
+ struct xer__cb_arg arg;
+ int new_stateContext = *stateContext;
+ ssize_t ret;
+
+ arg.callback_not_invoked = 1;
+ ret = pxml_parse(&new_stateContext, buffer, size, xer__token_cb, &arg);
+ if(ret < 0) return -1;
+ if(arg.callback_not_invoked) {
+ assert(ret == 0); /* No data was consumed */
+ return 0; /* Try again with more data */
+ } else {
+ assert(arg.chunk_size);
+ assert(arg.chunk_buf == buffer);
+ }
+
+ /*
+ * Translate the XML chunk types into more convenient ones.
+ */
+ switch(arg.chunk_type) {
+ case PXML_TEXT:
+ *ch_type = PXER_TEXT;
+ break;
+ case PXML_TAG: return 0; /* Want more */
+ case PXML_TAG_END:
+ *ch_type = PXER_TAG;
+ break;
+ case PXML_COMMENT:
+ case PXML_COMMENT_END:
+ *ch_type = PXER_COMMENT;
+ break;
+ }
+
+ *stateContext = new_stateContext;
+ return arg.chunk_size;
+}
+
+#define CSLASH 0x2f /* '/' */
+#define LANGLE 0x3c /* '<' */
+#define RANGLE 0x3e /* '>' */
+
+xer_check_tag_e
+xer_check_tag(const void *buf_ptr, int size, const char *need_tag) {
+ const char *buf = (const char *)buf_ptr;
+ const char *end;
+ xer_check_tag_e ct = XCT_OPENING;
+
+ if(size < 2 || buf[0] != LANGLE || buf[size-1] != RANGLE) {
+ if(size >= 2)
+ ASN_DEBUG("Broken XML tag: \"%c...%c\"", buf[0], buf[size - 1]);
+ return XCT_BROKEN;
+ }
+
+ /*
+ * Determine the tag class.
+ */
+ if(buf[1] == CSLASH) {
+ buf += 2; /* advance past "</" */
+ size -= 3; /* strip "</" and ">" */
+ ct = XCT_CLOSING;
+ if(size > 0 && buf[size-1] == CSLASH)
+ return XCT_BROKEN; /* </abc/> */
+ } else {
+ buf++; /* advance past "<" */
+ size -= 2; /* strip "<" and ">" */
+ if(size > 0 && buf[size-1] == CSLASH) {
+ ct = XCT_BOTH;
+ size--; /* One more, for "/" */
+ }
+ }
+
+ /* Sometimes we don't care about the tag */
+ if(!need_tag || !*need_tag)
+ return (xer_check_tag_e)(XCT__UNK__MASK | ct);
+
+ /*
+ * Determine the tag name.
+ */
+ for(end = buf + size; buf < end; buf++, need_tag++) {
+ int b = *buf, n = *need_tag;
+ if(b != n) {
+ if(n == 0) {
+ switch(b) {
+ case 0x09: case 0x0a: case 0x0c: case 0x0d:
+ case 0x20:
+ /* "<abc def/>": whitespace is normal */
+ return ct;
+ }
+ }
+ return (xer_check_tag_e)(XCT__UNK__MASK | ct);
+ }
+ if(b == 0)
+ return XCT_BROKEN; /* Embedded 0 in buf?! */
+ }
+ if(*need_tag)
+ return (xer_check_tag_e)(XCT__UNK__MASK | ct);
+
+ return ct;
+}
+
+
+#undef ADVANCE
+#define ADVANCE(num_bytes) do { \
+ size_t num = (num_bytes); \
+ buf_ptr = ((const char *)buf_ptr) + num; \
+ size -= num; \
+ consumed_myself += num; \
+ } while(0)
+
+#undef RETURN
+#define RETURN(_code) do { \
+ rval.code = _code; \
+ rval.consumed = consumed_myself; \
+ if(rval.code != RC_OK) \
+ ASN_DEBUG("Failed with %d", rval.code); \
+ return rval; \
+ } while(0)
+
+#define XER_GOT_BODY(chunk_buf, chunk_size, size) do { \
+ ssize_t converted_size = body_receiver \
+ (struct_key, chunk_buf, chunk_size, \
+ (size_t)chunk_size < size); \
+ if(converted_size == -1) RETURN(RC_FAIL); \
+ if(converted_size == 0 \
+ && size == (size_t)chunk_size) \
+ RETURN(RC_WMORE); \
+ chunk_size = converted_size; \
+ } while(0)
+#define XER_GOT_EMPTY() do { \
+ if(body_receiver(struct_key, 0, 0, size > 0) == -1) \
+ RETURN(RC_FAIL); \
+ } while(0)
+
+/*
+ * Generalized function for decoding the primitive values.
+ */
+asn_dec_rval_t
+xer_decode_general(asn_codec_ctx_t *opt_codec_ctx,
+ asn_struct_ctx_t *ctx, /* Type decoder context */
+ void *struct_key,
+ const char *xml_tag, /* Expected XML tag */
+ const void *buf_ptr, size_t size,
+ int (*opt_unexpected_tag_decoder)
+ (void *struct_key, const void *chunk_buf, size_t chunk_size),
+ ssize_t (*body_receiver)
+ (void *struct_key, const void *chunk_buf, size_t chunk_size,
+ int have_more)
+ ) {
+
+ asn_dec_rval_t rval;
+ ssize_t consumed_myself = 0;
+
+ (void)opt_codec_ctx;
+
+ /*
+ * Phases of XER/XML processing:
+ * Phase 0: Check that the opening tag matches our expectations.
+ * Phase 1: Processing body and reacting on closing tag.
+ */
+ if(ctx->phase > 1) RETURN(RC_FAIL);
+ for(;;) {
+ pxer_chunk_type_e ch_type; /* XER chunk type */
+ ssize_t ch_size; /* Chunk size */
+ xer_check_tag_e tcv; /* Tag check value */
+
+ /*
+ * Get the next part of the XML stream.
+ */
+ ch_size = xer_next_token(&ctx->context, buf_ptr, size,
+ &ch_type);
+ switch(ch_size) {
+ case -1: RETURN(RC_FAIL);
+ case 0:
+ RETURN(RC_WMORE);
+ default:
+ switch(ch_type) {
+ case PXER_COMMENT: /* Got XML comment */
+ ADVANCE(ch_size); /* Skip silently */
+ continue;
+ case PXER_TEXT:
+ if(ctx->phase == 0) {
+ /*
+ * We have to ignore whitespace here,
+ * but in order to be forward compatible
+ * with EXTENDED-XER (EMBED-VALUES, #25)
+ * any text is just ignored here.
+ */
+ } else {
+ XER_GOT_BODY(buf_ptr, ch_size, size);
+ }
+ ADVANCE(ch_size);
+ continue;
+ case PXER_TAG:
+ break; /* Check the rest down there */
+ }
+ }
+
+ assert(ch_type == PXER_TAG && size);
+
+ tcv = xer_check_tag(buf_ptr, ch_size, xml_tag);
+ /*
+ * Phase 0:
+ * Expecting the opening tag
+ * for the type being processed.
+ * Phase 1:
+ * Waiting for the closing XML tag.
+ */
+ switch(tcv) {
+ case XCT_BOTH:
+ if(ctx->phase) break;
+ /* Finished decoding of an empty element */
+ XER_GOT_EMPTY();
+ ADVANCE(ch_size);
+ ctx->phase = 2; /* Phase out */
+ RETURN(RC_OK);
+ case XCT_OPENING:
+ if(ctx->phase) break;
+ ADVANCE(ch_size);
+ ctx->phase = 1; /* Processing body phase */
+ continue;
+ case XCT_CLOSING:
+ if(!ctx->phase) break;
+ ADVANCE(ch_size);
+ ctx->phase = 2; /* Phase out */
+ RETURN(RC_OK);
+ case XCT_UNKNOWN_BO:
+ /*
+ * Certain tags in the body may be expected.
+ */
+ if(opt_unexpected_tag_decoder
+ && opt_unexpected_tag_decoder(struct_key,
+ buf_ptr, ch_size) >= 0) {
+ /* Tag's processed fine */
+ ADVANCE(ch_size);
+ if(!ctx->phase) {
+ /* We are not expecting
+ * the closing tag anymore. */
+ ctx->phase = 2; /* Phase out */
+ RETURN(RC_OK);
+ }
+ continue;
+ }
+ /* Fall through */
+ default:
+ break; /* Unexpected tag */
+ }
+
+ ASN_DEBUG("Unexpected XML tag (expected \"%s\")", xml_tag);
+ break; /* Dark and mysterious things have just happened */
+ }
+
+ RETURN(RC_FAIL);
+}
+
+
+int
+xer_is_whitespace(const void *chunk_buf, size_t chunk_size) {
+ const char *p = (const char *)chunk_buf;
+ const char *pend = p + chunk_size;
+
+ for(; p < pend; p++) {
+ switch(*p) {
+ /* X.693, #8.1.4
+ * HORISONTAL TAB (9)
+ * LINE FEED (10)
+ * CARRIAGE RETURN (13)
+ * SPACE (32)
+ */
+ case 0x09: case 0x0a: case 0x0d: case 0x20:
+ break;
+ default:
+ return 0;
+ }
+ }
+ return 1; /* All whitespace */
+}
+
+/*
+ * This is a vastly simplified, non-validating XML tree skipper.
+ */
+int
+xer_skip_unknown(xer_check_tag_e tcv, ber_tlv_len_t *depth) {
+ assert(*depth > 0);
+ switch(tcv) {
+ case XCT_BOTH:
+ case XCT_UNKNOWN_BO:
+ /* These negate each other. */
+ return 0;
+ case XCT_OPENING:
+ case XCT_UNKNOWN_OP:
+ ++(*depth);
+ return 0;
+ case XCT_CLOSING:
+ case XCT_UNKNOWN_CL:
+ if(--(*depth) == 0)
+ return (tcv == XCT_CLOSING) ? 2 : 1;
+ return 0;
+ default:
+ return -1;
+ }
+}
--- /dev/null
+/*-
+ * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#include <asn_internal.h>
+#include <stdio.h>
+#include <errno.h>
+
+/*
+ * The XER encoder of any type. May be invoked by the application.
+ */
+asn_enc_rval_t
+xer_encode(asn_TYPE_descriptor_t *td, void *sptr,
+ enum xer_encoder_flags_e xer_flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ asn_enc_rval_t er, tmper;
+ const char *mname;
+ size_t mlen;
+ int xcan = (xer_flags & XER_F_CANONICAL) ? 1 : 2;
+
+ if(!td || !sptr) goto cb_failed;
+
+ mname = td->xml_tag;
+ mlen = strlen(mname);
+
+ _ASN_CALLBACK3("<", 1, mname, mlen, ">", 1);
+
+ tmper = td->xer_encoder(td, sptr, 1, xer_flags, cb, app_key);
+ if(tmper.encoded == -1) return tmper;
+
+ _ASN_CALLBACK3("</", 2, mname, mlen, ">\n", xcan);
+
+ er.encoded = 4 + xcan + (2 * mlen) + tmper.encoded;
+
+ _ASN_ENCODED_OK(er);
+cb_failed:
+ _ASN_ENCODE_FAILED;
+}
+
+/*
+ * This is a helper function for xer_fprint, which directs all incoming data
+ * into the provided file descriptor.
+ */
+static int
+xer__print2fp(const void *buffer, size_t size, void *app_key) {
+ FILE *stream = (FILE *)app_key;
+
+ if(fwrite(buffer, 1, size, stream) != size)
+ return -1;
+
+ return 0;
+}
+
+int
+xer_fprint(FILE *stream, asn_TYPE_descriptor_t *td, void *sptr) {
+ asn_enc_rval_t er;
+
+ if(!stream) stream = stdout;
+ if(!td || !sptr)
+ return -1;
+
+ er = xer_encode(td, sptr, XER_F_BASIC, xer__print2fp, stream);
+ if(er.encoded == -1)
+ return -1;
+
+ return fflush(stream);
+}
--- /dev/null
+/*
+ * Copyright (c) 2003, 2004 X/IO Labs, xiolabs.com.
+ * Copyright (c) 2003, 2004, 2005 Lev Walkin <vlm@lionet.info>.
+ * All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#include <asn_system.h>
+#include <xer_support.h>
+
+/* Parser states */
+typedef enum {
+ ST_TEXT,
+ ST_TAG_START,
+ ST_TAG_BODY,
+ ST_TAG_QUOTE_WAIT,
+ ST_TAG_QUOTED_STRING,
+ ST_TAG_UNQUOTED_STRING,
+ ST_COMMENT_WAIT_DASH1, /* "<!--"[1] */
+ ST_COMMENT_WAIT_DASH2, /* "<!--"[2] */
+ ST_COMMENT,
+ ST_COMMENT_CLO_DASH2, /* "-->"[0] */
+ ST_COMMENT_CLO_RT /* "-->"[1] */
+} pstate_e;
+
+static pxml_chunk_type_e final_chunk_type[] = {
+ PXML_TEXT,
+ PXML_TAG_END,
+ PXML_COMMENT_END,
+ PXML_TAG_END,
+ PXML_COMMENT_END,
+};
+
+
+static int
+_charclass[256] = {
+ 0,0,0,0,0,0,0,0, 0,1,1,0,1,1,0,0,
+ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
+ 1,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
+ 2,2,2,2,2,2,2,2, 2,2,0,0,0,0,0,0, /* 01234567 89 */
+ 0,3,3,3,3,3,3,3, 3,3,3,3,3,3,3,3, /* ABCDEFG HIJKLMNO */
+ 3,3,3,3,3,3,3,3, 3,3,3,0,0,0,0,0, /* PQRSTUVW XYZ */
+ 0,3,3,3,3,3,3,3, 3,3,3,3,3,3,3,3, /* abcdefg hijklmno */
+ 3,3,3,3,3,3,3,3, 3,3,3,0,0,0,0,0 /* pqrstuvw xyz */
+};
+#define WHITESPACE(c) (_charclass[(unsigned char)(c)] == 1)
+#define ALNUM(c) (_charclass[(unsigned char)(c)] >= 2)
+#define ALPHA(c) (_charclass[(unsigned char)(c)] == 3)
+
+/* Aliases for characters, ASCII/UTF-8 */
+#define EXCLAM 0x21 /* '!' */
+#define CQUOTE 0x22 /* '"' */
+#define CDASH 0x2d /* '-' */
+#define CSLASH 0x2f /* '/' */
+#define LANGLE 0x3c /* '<' */
+#define CEQUAL 0x3d /* '=' */
+#define RANGLE 0x3e /* '>' */
+#define CQUEST 0x3f /* '?' */
+
+/* Invoke token callback */
+#define TOKEN_CB_CALL(type, _ns, _current_too, _final) do { \
+ int _ret; \
+ pstate_e ns = _ns; \
+ ssize_t _sz = (p - chunk_start) + _current_too; \
+ if (!_sz) { \
+ /* Shortcut */ \
+ state = _ns; \
+ break; \
+ } \
+ _ret = cb(type, chunk_start, _sz, key); \
+ if(_ret < _sz) { \
+ if(_current_too && _ret == -1) \
+ state = ns; \
+ goto finish; \
+ } \
+ chunk_start = p + _current_too; \
+ state = ns; \
+ } while(0)
+
+#define TOKEN_CB(_type, _ns, _current_too) \
+ TOKEN_CB_CALL(_type, _ns, _current_too, 0)
+
+#define TOKEN_CB_FINAL(_type, _ns, _current_too) \
+ TOKEN_CB_CALL(final_chunk_type[_type], _ns, _current_too, 1)
+
+/*
+ * Parser itself
+ */
+ssize_t pxml_parse(int *stateContext, const void *xmlbuf, size_t size, pxml_callback_f *cb, void *key) {
+ pstate_e state = (pstate_e)*stateContext;
+ const char *chunk_start = (const char *)xmlbuf;
+ const char *p = chunk_start;
+ const char *end = p + size;
+
+ for(; p < end; p++) {
+ int C = *(const unsigned char *)p;
+ switch(state) {
+ case ST_TEXT:
+ /*
+ * Initial state: we're in the middle of some text,
+ * or just have started.
+ */
+ if (C == LANGLE)
+ /* We're now in the tag, probably */
+ TOKEN_CB(PXML_TEXT, ST_TAG_START, 0);
+ break;
+ case ST_TAG_START:
+ if (ALPHA(C) || (C == CSLASH))
+ state = ST_TAG_BODY;
+ else if (C == EXCLAM)
+ state = ST_COMMENT_WAIT_DASH1;
+ else
+ /*
+ * Not characters and not whitespace.
+ * Must be something like "3 < 4".
+ */
+ TOKEN_CB(PXML_TEXT, ST_TEXT, 1);/* Flush as data */
+ break;
+ case ST_TAG_BODY:
+ switch(C) {
+ case RANGLE:
+ /* End of the tag */
+ TOKEN_CB_FINAL(PXML_TAG, ST_TEXT, 1);
+ break;
+ case LANGLE:
+ /*
+ * The previous tag wasn't completed, but still
+ * recognized as valid. (Mozilla-compatible)
+ */
+ TOKEN_CB_FINAL(PXML_TAG, ST_TAG_START, 0);
+ break;
+ case CEQUAL:
+ state = ST_TAG_QUOTE_WAIT;
+ break;
+ }
+ break;
+ case ST_TAG_QUOTE_WAIT:
+ /*
+ * State after the equal sign ("=") in the tag.
+ */
+ switch(C) {
+ case CQUOTE:
+ state = ST_TAG_QUOTED_STRING;
+ break;
+ case RANGLE:
+ /* End of the tag */
+ TOKEN_CB_FINAL(PXML_TAG, ST_TEXT, 1);
+ break;
+ default:
+ if(!WHITESPACE(C))
+ /* Unquoted string value */
+ state = ST_TAG_UNQUOTED_STRING;
+ }
+ break;
+ case ST_TAG_QUOTED_STRING:
+ /*
+ * Tag attribute's string value in quotes.
+ */
+ if(C == CQUOTE) {
+ /* Return back to the tag state */
+ state = ST_TAG_BODY;
+ }
+ break;
+ case ST_TAG_UNQUOTED_STRING:
+ if(C == RANGLE) {
+ /* End of the tag */
+ TOKEN_CB_FINAL(PXML_TAG, ST_TEXT, 1);
+ } else if(WHITESPACE(C)) {
+ /* Return back to the tag state */
+ state = ST_TAG_BODY;
+ }
+ break;
+ case ST_COMMENT_WAIT_DASH1:
+ if(C == CDASH) {
+ state = ST_COMMENT_WAIT_DASH2;
+ } else {
+ /* Some ordinary tag. */
+ state = ST_TAG_BODY;
+ }
+ break;
+ case ST_COMMENT_WAIT_DASH2:
+ if(C == CDASH) {
+ /* Seen "<--" */
+ state = ST_COMMENT;
+ } else {
+ /* Some ordinary tag */
+ state = ST_TAG_BODY;
+ }
+ break;
+ case ST_COMMENT:
+ if(C == CDASH) {
+ state = ST_COMMENT_CLO_DASH2;
+ }
+ break;
+ case ST_COMMENT_CLO_DASH2:
+ if(C == CDASH) {
+ state = ST_COMMENT_CLO_RT;
+ } else {
+ /* This is not an end of a comment */
+ state = ST_COMMENT;
+ }
+ break;
+ case ST_COMMENT_CLO_RT:
+ if(C == RANGLE) {
+ TOKEN_CB_FINAL(PXML_COMMENT, ST_TEXT, 1);
+ } else if(C == CDASH) {
+ /* Maintain current state, still waiting for '>' */
+ } else {
+ state = ST_COMMENT;
+ }
+ break;
+ } /* switch(*ptr) */
+ } /* for() */
+
+ /*
+ * Flush the partially processed chunk, state permitting.
+ */
+ if(p - chunk_start) {
+ switch (state) {
+ case ST_COMMENT:
+ TOKEN_CB(PXML_COMMENT, state, 0);
+ break;
+ case ST_TEXT:
+ TOKEN_CB(PXML_TEXT, state, 0);
+ break;
+ default: break; /* a no-op */
+ }
+ }
+
+finish:
+ *stateContext = (int)state;
+ return chunk_start - (const char *)xmlbuf;
+}
+
INCS = servconf.h \
netunit.h
+LIB_INCS = -I ../common.lib/include \
+ -I ../crypto.lib/include
+
include ../Makefile.in
--- /dev/null
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Author : Boris Mikhailenko <stg34@stargazer.dp.ua>
+ */
+
+ /*
+ $Revision: 1.6 $
+ $Date: 2010/02/11 12:32:53 $
+ $Author: faust $
+ */
+
+#ifndef NetUnitH
+#define NetUnitH
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+#include <list>
+#include <string>
+
+#include "stg/blowfish.h"
+
+#define STG_HEADER "SG04"
+#define OK_HEADER "OKHD"
+#define ERR_HEADER "ERHD"
+#define OK_LOGIN "OKLG"
+#define ERR_LOGIN "ERLG"
+#define OK_LOGINS "OKLS"
+#define ERR_LOGINS "ERLS"
+
+// äÌÉÎÎÁ ÛÉÆÒÕÅÍÏÇÏ É ÐÅÒÅÄÁ×ÁÅÍÏÇ ÚÁ ÏÄÉÎ ÒÁÚ ÂÌÏËÁ ÉÎÆÏÒÍÁÃÉÉ
+#define ENC_MSG_LEN (8)
+
+#define MAX_ERR_STR_LEN (64)
+
+typedef int(*RxCallback_t)(void *, std::list<std::string> *);
+
+enum status
+{
+st_ok = 0,
+st_conn_fail,
+st_send_fail,
+st_recv_fail,
+st_header_err,
+st_login_err,
+st_logins_err,
+st_data_err,
+st_unknown_err,
+st_dns_err,
+st_xml_parse_error,
+st_data_error
+};
+
+enum CONF_STATE
+{
+confHdr = 0,
+confLogin,
+confLoginCipher,
+confData
+};
+//---------------------------------------------------------------------------
+class NETTRANSACT
+{
+public:
+ NETTRANSACT();
+ int Transact(const char * data);
+ const std::string & GetError() const;
+
+ void SetRxCallback(void * data, RxCallback_t);
+
+ void SetServer(const char * serverName);
+ void SetServerPort(short unsigned p);
+
+ void SetLogin(const char * l);
+ void SetPassword(const char * p);
+ ////////////////////////////////////////////
+ int Connect();
+ int Disconnect();
+ void Reset();
+private:
+ int TxHeader();
+ int RxHeaderAnswer();
+
+ int TxLogin();
+ int RxLoginAnswer();
+
+ int TxLoginS();
+ int RxLoginSAnswer();
+
+ int TxData(const char * text);
+ int TxData(char * data);
+ int RxDataAnswer();
+
+ void Encrypt(char * d, const char * s, BLOWFISH_CTX *ctx);
+ void EnDecryptInit(const char * passwd, int passwdLen, BLOWFISH_CTX *ctx);
+ void Decrypt(char * d, const char * s, BLOWFISH_CTX *ctx);
+
+ std::string server;
+ short unsigned port;
+ std::string login;
+ std::string password;
+ int outerSocket;
+ std::list<std::string> answerList;
+ RxCallback_t RxCallBack;
+ void * dataRxCallBack;
+ std::string errorMsg;
+};
+//---------------------------------------------------------------------------
+#endif
--- /dev/null
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Author : Boris Mikhailenko <stg34@stargazer.dp.ua>
+ */
+
+ /*
+ $Revision: 1.10 $
+ $Date: 2009/03/17 09:52:35 $
+ $Author: faust $
+ */
+
+#ifndef SERVCONF_H
+#define SERVCONF_H
+
+#include <expat.h>
+
+#include <list>
+#include <string>
+
+#include "stg/os_int.h"
+#include "stg/const.h"
+#include "netunit.h"
+
+void Start(void *data, const char *el, const char **attr);
+void End(void *data, const char *el);
+
+#define MAX_ERR_STR_LEN (64)
+#define IP_STRING_LEN (255)
+#define UNAME_LEN (256)
+#define SERV_VER_LEN (64)
+#define DIRNAME_LEN (16)
+
+//-----------------------------------------------------------------------------
+struct STAT
+{
+ long long su[DIR_NUM];
+ long long sd[DIR_NUM];
+ long long mu[DIR_NUM];
+ long long md[DIR_NUM];
+ double freeMb;
+};
+//-----------------------------------------------------------------------------
+struct SERVERINFO
+{
+ std::string version;
+ int tariffNum;
+ int tariffType;
+ int usersNum;
+ std::string uname;
+ int dirNum;
+ std::string dirName[DIR_NUM];
+};
+//-----------------------------------------------------------------------------
+struct USERDATA
+{
+ std::string login;
+ std::string password;
+ double cash;
+ double credit;
+ time_t creditExpire;
+ double lastCash;
+ double prepaidTraff;
+ int down;
+ int passive;
+ int disableDetailStat;
+ int connected;
+ int alwaysOnline;
+ uint32_t ip;
+ std::string ips;
+ std::string tariff;
+ std::string iface;
+ std::string group;
+ std::string note;
+ std::string email;
+ std::string name;
+ std::string address;
+ std::string phone;
+ STAT stat;
+ std::string userData[USERDATA_NUM];
+
+ struct USERDATA * next;
+};
+//-----------------------------------------------------------------------------
+typedef void(*RecvUserDataCb_t)(USERDATA * ud, void * data);
+typedef void(*RecvServerInfoDataCb_t)(SERVERINFO * si, void * data);
+typedef int(*RecvChgUserCb_t)(const char * asnwer, void * data);
+typedef int(*RecvCheckUserCb_t)(const char * answer, void * data);
+typedef int(*RecvSendMessageCb_t)(const char * answer, void * data);
+//-----------------------------------------------------------------------------
+struct ADMINDATA
+{
+ char login[ADM_LOGIN_LEN];
+};
+//-----------------------------------------------------------------------------
+class PARSER
+{
+public:
+ PARSER() {}
+ virtual ~PARSER() {}
+ virtual int ParseStart(const char *el, const char **attr) = 0;
+ virtual void ParseEnd(const char *el) = 0;
+};
+//-----------------------------------------------------------------------------
+class PARSER_CHG_USER: public PARSER
+{
+public:
+ PARSER_CHG_USER();
+ int ParseStart(const char *el, const char **attr);
+ void ParseEnd(const char *el);
+ void ParseAnswer(const char *el, const char **attr);
+ void SetChgUserRecvCb(RecvChgUserCb_t, void * data);
+private:
+ RecvChgUserCb_t RecvChgUserCb;
+ void * chgUserCbData;
+ int depth;
+ bool error;
+};
+//-----------------------------------------------------------------------------
+class PARSER_CHECK_USER: public PARSER
+{
+public:
+ PARSER_CHECK_USER();
+ int ParseStart(const char *el, const char **attr);
+ void ParseEnd(const char *el);
+ void ParseAnswer(const char *el, const char **attr);
+ void SetCheckUserRecvCb(RecvCheckUserCb_t, void * data);
+private:
+ RecvCheckUserCb_t RecvCheckUserCb;
+ void * checkUserCbData;
+ int depth;
+ bool error;
+};
+//-----------------------------------------------------------------------------
+class PARSER_GET_USERS: public PARSER
+{
+public:
+ PARSER_GET_USERS();
+ int ParseStart(const char *el, const char **attr);
+ void ParseEnd(const char *el);
+ void ParseUsers(const char *el, const char **attr);
+ void ParseUser(const char *el, const char **attr);
+ void ParseUserParams(const char *el, const char **attr);
+ void ParseUserLoadStat(const char * el, const char ** attr);
+ void SetUserDataRecvCb(RecvUserDataCb_t, void * data);
+private:
+ RecvUserDataCb_t RecvUserDataCb;
+ void * userDataCb;
+ USERDATA user;
+ int depth;
+ bool error;
+};
+//-----------------------------------------------------------------------------
+class PARSER_GET_USER: public PARSER
+{
+public:
+ PARSER_GET_USER();
+ int ParseStart(const char *el, const char **attr);
+ void ParseEnd(const char *el);
+ void ParseUsers(const char *el, const char **attr);
+ void ParseUser(const char *el, const char **attr);
+ void ParseUserParams(const char *el, const char **attr);
+ void ParseUserLoadStat(const char * el, const char ** attr);
+ void SetUserDataRecvCb(RecvUserDataCb_t, void * data);
+private:
+ RecvUserDataCb_t RecvUserDataCb;
+ void * userDataCb;
+ USERDATA user;
+ int depth;
+ bool error;
+};
+//-----------------------------------------------------------------------------
+class PARSER_GET_SERVER_INFO: public PARSER
+{
+public:
+ PARSER_GET_SERVER_INFO();
+ int ParseStart(const char *el, const char **attr);
+ void ParseEnd(const char *el);
+ void ParseServerInfo(const char *el, const char **attr);
+ bool GetError();
+ void SetServerInfoRecvCb(RecvServerInfoDataCb_t, void * data);
+private:
+ void ParseUname(const char ** attr);
+ void ParseServerVersion(const char ** attr);
+ void ParseUsersNum(const char ** attr);
+ void ParseTariffsNum(const char ** attr);
+ void ParseTariffType(const char ** attr);
+ void ParseDirNum(const char **attr);
+ void ParseDirName(const char **attr, int d);
+
+ RecvServerInfoDataCb_t RecvServerInfoDataCb;
+ void * serverInfoDataCb;
+ int depth;
+ bool error;
+ SERVERINFO serverInfo;
+};
+//-----------------------------------------------------------------------------
+class PARSER_SEND_MESSAGE: public PARSER
+{
+public:
+ PARSER_SEND_MESSAGE();
+ int ParseStart(const char *el, const char **attr);
+ void ParseEnd(const char *el);
+ void ParseAnswer(const char *el, const char **attr);
+ void SetSendMessageRecvCb(RecvSendMessageCb_t, void * data);
+private:
+ RecvSendMessageCb_t RecvSendMessageCb;
+ void * sendMessageCbData;
+ int depth;
+ bool error;
+};
+//-----------------------------------------------------------------------------
+class SERVCONF
+{
+public:
+ SERVCONF();
+ void SetServer(const char * server);
+ void SetPort(uint16_t port);
+
+ void SetAdmLogin(const char * login);
+ void SetAdmPassword(const char * password);
+
+ void SetUserDataRecvCb(RecvUserDataCb_t, void * data);
+ void SetServerInfoRecvCb(RecvServerInfoDataCb_t, void * data);
+ void SetChgUserCb(RecvChgUserCb_t, void * data);
+ void SetCheckUserCb(RecvCheckUserCb_t, void * data);
+ void SetGetUserDataRecvCb(RecvUserDataCb_t, void * data);
+ void SetSendMessageCb(RecvSendMessageCb_t, void * data);
+
+ int GetUsers();
+ int GetUser(const char * login);
+ int ChgUser(const char * request);
+ // TODO: Remove this shit!
+ int MsgUser(const char * request);
+ int SendMessage(const char * login, const char * message, int prio);
+ int GetServerInfo();
+ int CheckUser(const char * login, const char * password);
+
+ const std::string & GetStrError() const;
+ int GetError();
+ int Start(const char *el, const char **attr);
+ void End(const char *el);
+
+private:
+ PARSER * currParser;
+
+ PARSER_GET_USERS parserGetUsers;
+ PARSER_GET_USER parserGetUser;
+ PARSER_GET_SERVER_INFO parserServerInfo;
+ PARSER_CHG_USER parserChgUser;
+ PARSER_CHECK_USER parserCheckUser;
+ PARSER_SEND_MESSAGE parserSendMessage;
+
+ NETTRANSACT nt;
+ int parseDepth;
+
+ std::string errorMsg;
+ int error;
+ XML_Parser parser;
+
+ RecvUserDataCb_t RecvUserDataCb;
+ RecvUserDataCb_t RecvGetUserDataCb;
+ RecvServerInfoDataCb_t RecvServerInfoDataCb;
+ RecvChgUserCb_t RecvChgUserCb;
+ RecvCheckUserCb_t RecvCheckUserCb;
+ RecvSendMessageCb_t RecvSendMessageCb;
+
+ void * getUserDataDataCb;
+ void * getUsersDataDataCb;
+ void * getServerInfoDataCb;
+ void * chgUserDataCb;
+ void * checkUserDataCb;
+ void * sendMessageDataCb;
+
+ friend int AnsRecv(void * data, std::list<std::string> * list);
+};
+//-----------------------------------------------------------------------------
+
+#endif /* _SERVCONF_H_ */
#include <cstdio>
#include <cstring>
-#include "netunit.h"
+#include "stg/netunit.h"
#include "stg/common.h"
//---------------------------------------------------------------------------
+++ /dev/null
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/*
- * Author : Boris Mikhailenko <stg34@stargazer.dp.ua>
- */
-
- /*
- $Revision: 1.6 $
- $Date: 2010/02/11 12:32:53 $
- $Author: faust $
- */
-
-#ifndef NetUnitH
-#define NetUnitH
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-
-#include <list>
-#include <string>
-
-#include "stg/blowfish.h"
-
-#define STG_HEADER "SG04"
-#define OK_HEADER "OKHD"
-#define ERR_HEADER "ERHD"
-#define OK_LOGIN "OKLG"
-#define ERR_LOGIN "ERLG"
-#define OK_LOGINS "OKLS"
-#define ERR_LOGINS "ERLS"
-
-// äÌÉÎÎÁ ÛÉÆÒÕÅÍÏÇÏ É ÐÅÒÅÄÁ×ÁÅÍÏÇ ÚÁ ÏÄÉÎ ÒÁÚ ÂÌÏËÁ ÉÎÆÏÒÍÁÃÉÉ
-#define ENC_MSG_LEN (8)
-
-#define MAX_ERR_STR_LEN (64)
-
-typedef int(*RxCallback_t)(void *, std::list<std::string> *);
-
-enum status
-{
-st_ok = 0,
-st_conn_fail,
-st_send_fail,
-st_recv_fail,
-st_header_err,
-st_login_err,
-st_logins_err,
-st_data_err,
-st_unknown_err,
-st_dns_err,
-st_xml_parse_error,
-st_data_error
-};
-
-enum CONF_STATE
-{
-confHdr = 0,
-confLogin,
-confLoginCipher,
-confData
-};
-//---------------------------------------------------------------------------
-class NETTRANSACT
-{
-public:
- NETTRANSACT();
- int Transact(const char * data);
- const std::string & GetError() const;
-
- void SetRxCallback(void * data, RxCallback_t);
-
- void SetServer(const char * serverName);
- void SetServerPort(short unsigned p);
-
- void SetLogin(const char * l);
- void SetPassword(const char * p);
- ////////////////////////////////////////////
- int Connect();
- int Disconnect();
- void Reset();
-private:
- int TxHeader();
- int RxHeaderAnswer();
-
- int TxLogin();
- int RxLoginAnswer();
-
- int TxLoginS();
- int RxLoginSAnswer();
-
- int TxData(const char * text);
- int TxData(char * data);
- int RxDataAnswer();
-
- void Encrypt(char * d, const char * s, BLOWFISH_CTX *ctx);
- void EnDecryptInit(const char * passwd, int passwdLen, BLOWFISH_CTX *ctx);
- void Decrypt(char * d, const char * s, BLOWFISH_CTX *ctx);
-
- std::string server;
- short unsigned port;
- std::string login;
- std::string password;
- int outerSocket;
- std::list<std::string> answerList;
- RxCallback_t RxCallBack;
- void * dataRxCallBack;
- std::string errorMsg;
-};
-//---------------------------------------------------------------------------
-#endif
#include "stg/common.h"
#include "stg/const.h"
-#include "servconf.h"
+#include "stg/servconf.h"
using namespace std;
#include <cstring>
#include "stg/common.h"
-#include "servconf.h"
+#include "stg/servconf.h"
using namespace std;
+++ /dev/null
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/*
- * Author : Boris Mikhailenko <stg34@stargazer.dp.ua>
- */
-
- /*
- $Revision: 1.10 $
- $Date: 2009/03/17 09:52:35 $
- $Author: faust $
- */
-
-#ifndef SERVCONF_H
-#define SERVCONF_H
-
-#include <expat.h>
-
-#include <list>
-#include <string>
-
-#include "stg/os_int.h"
-#include "stg/const.h"
-#include "netunit.h"
-
-void Start(void *data, const char *el, const char **attr);
-void End(void *data, const char *el);
-
-#define MAX_ERR_STR_LEN (64)
-#define IP_STRING_LEN (255)
-#define UNAME_LEN (256)
-#define SERV_VER_LEN (64)
-#define DIRNAME_LEN (16)
-
-//-----------------------------------------------------------------------------
-struct STAT
-{
- long long su[DIR_NUM];
- long long sd[DIR_NUM];
- long long mu[DIR_NUM];
- long long md[DIR_NUM];
- double freeMb;
-};
-//-----------------------------------------------------------------------------
-struct SERVERINFO
-{
- std::string version;
- int tariffNum;
- int tariffType;
- int usersNum;
- std::string uname;
- int dirNum;
- std::string dirName[DIR_NUM];
-};
-//-----------------------------------------------------------------------------
-struct USERDATA
-{
- std::string login;
- std::string password;
- double cash;
- double credit;
- time_t creditExpire;
- double lastCash;
- double prepaidTraff;
- int down;
- int passive;
- int disableDetailStat;
- int connected;
- int alwaysOnline;
- uint32_t ip;
- std::string ips;
- std::string tariff;
- std::string iface;
- std::string group;
- std::string note;
- std::string email;
- std::string name;
- std::string address;
- std::string phone;
- STAT stat;
- std::string userData[USERDATA_NUM];
-
- struct USERDATA * next;
-};
-//-----------------------------------------------------------------------------
-typedef void(*RecvUserDataCb_t)(USERDATA * ud, void * data);
-typedef void(*RecvServerInfoDataCb_t)(SERVERINFO * si, void * data);
-typedef int(*RecvChgUserCb_t)(const char * asnwer, void * data);
-typedef int(*RecvCheckUserCb_t)(const char * answer, void * data);
-typedef int(*RecvSendMessageCb_t)(const char * answer, void * data);
-//-----------------------------------------------------------------------------
-struct ADMINDATA
-{
- char login[ADM_LOGIN_LEN];
-};
-//-----------------------------------------------------------------------------
-class PARSER
-{
-public:
- PARSER() {}
- virtual ~PARSER() {}
- virtual int ParseStart(const char *el, const char **attr) = 0;
- virtual void ParseEnd(const char *el) = 0;
-};
-//-----------------------------------------------------------------------------
-class PARSER_CHG_USER: public PARSER
-{
-public:
- PARSER_CHG_USER();
- int ParseStart(const char *el, const char **attr);
- void ParseEnd(const char *el);
- void ParseAnswer(const char *el, const char **attr);
- void SetChgUserRecvCb(RecvChgUserCb_t, void * data);
-private:
- RecvChgUserCb_t RecvChgUserCb;
- void * chgUserCbData;
- int depth;
- bool error;
-};
-//-----------------------------------------------------------------------------
-class PARSER_CHECK_USER: public PARSER
-{
-public:
- PARSER_CHECK_USER();
- int ParseStart(const char *el, const char **attr);
- void ParseEnd(const char *el);
- void ParseAnswer(const char *el, const char **attr);
- void SetCheckUserRecvCb(RecvCheckUserCb_t, void * data);
-private:
- RecvCheckUserCb_t RecvCheckUserCb;
- void * checkUserCbData;
- int depth;
- bool error;
-};
-//-----------------------------------------------------------------------------
-class PARSER_GET_USERS: public PARSER
-{
-public:
- PARSER_GET_USERS();
- int ParseStart(const char *el, const char **attr);
- void ParseEnd(const char *el);
- void ParseUsers(const char *el, const char **attr);
- void ParseUser(const char *el, const char **attr);
- void ParseUserParams(const char *el, const char **attr);
- void ParseUserLoadStat(const char * el, const char ** attr);
- void SetUserDataRecvCb(RecvUserDataCb_t, void * data);
-private:
- RecvUserDataCb_t RecvUserDataCb;
- void * userDataCb;
- USERDATA user;
- int depth;
- bool error;
-};
-//-----------------------------------------------------------------------------
-class PARSER_GET_USER: public PARSER
-{
-public:
- PARSER_GET_USER();
- int ParseStart(const char *el, const char **attr);
- void ParseEnd(const char *el);
- void ParseUsers(const char *el, const char **attr);
- void ParseUser(const char *el, const char **attr);
- void ParseUserParams(const char *el, const char **attr);
- void ParseUserLoadStat(const char * el, const char ** attr);
- void SetUserDataRecvCb(RecvUserDataCb_t, void * data);
-private:
- RecvUserDataCb_t RecvUserDataCb;
- void * userDataCb;
- USERDATA user;
- int depth;
- bool error;
-};
-//-----------------------------------------------------------------------------
-class PARSER_GET_SERVER_INFO: public PARSER
-{
-public:
- PARSER_GET_SERVER_INFO();
- int ParseStart(const char *el, const char **attr);
- void ParseEnd(const char *el);
- void ParseServerInfo(const char *el, const char **attr);
- bool GetError();
- void SetServerInfoRecvCb(RecvServerInfoDataCb_t, void * data);
-private:
- void ParseUname(const char ** attr);
- void ParseServerVersion(const char ** attr);
- void ParseUsersNum(const char ** attr);
- void ParseTariffsNum(const char ** attr);
- void ParseTariffType(const char ** attr);
- void ParseDirNum(const char **attr);
- void ParseDirName(const char **attr, int d);
-
- RecvServerInfoDataCb_t RecvServerInfoDataCb;
- void * serverInfoDataCb;
- int depth;
- bool error;
- SERVERINFO serverInfo;
-};
-//-----------------------------------------------------------------------------
-class PARSER_SEND_MESSAGE: public PARSER
-{
-public:
- PARSER_SEND_MESSAGE();
- int ParseStart(const char *el, const char **attr);
- void ParseEnd(const char *el);
- void ParseAnswer(const char *el, const char **attr);
- void SetSendMessageRecvCb(RecvSendMessageCb_t, void * data);
-private:
- RecvSendMessageCb_t RecvSendMessageCb;
- void * sendMessageCbData;
- int depth;
- bool error;
-};
-//-----------------------------------------------------------------------------
-class SERVCONF
-{
-public:
- SERVCONF();
- void SetServer(const char * server);
- void SetPort(uint16_t port);
-
- void SetAdmLogin(const char * login);
- void SetAdmPassword(const char * password);
-
- void SetUserDataRecvCb(RecvUserDataCb_t, void * data);
- void SetServerInfoRecvCb(RecvServerInfoDataCb_t, void * data);
- void SetChgUserCb(RecvChgUserCb_t, void * data);
- void SetCheckUserCb(RecvCheckUserCb_t, void * data);
- void SetGetUserDataRecvCb(RecvUserDataCb_t, void * data);
- void SetSendMessageCb(RecvSendMessageCb_t, void * data);
-
- int GetUsers();
- int GetUser(const char * login);
- int ChgUser(const char * request);
- // TODO: Remove this shit!
- int MsgUser(const char * request);
- int SendMessage(const char * login, const char * message, int prio);
- int GetServerInfo();
- int CheckUser(const char * login, const char * password);
-
- const std::string & GetStrError() const;
- int GetError();
- int Start(const char *el, const char **attr);
- void End(const char *el);
-
-private:
- PARSER * currParser;
-
- PARSER_GET_USERS parserGetUsers;
- PARSER_GET_USER parserGetUser;
- PARSER_GET_SERVER_INFO parserServerInfo;
- PARSER_CHG_USER parserChgUser;
- PARSER_CHECK_USER parserCheckUser;
- PARSER_SEND_MESSAGE parserSendMessage;
-
- NETTRANSACT nt;
- int parseDepth;
-
- std::string errorMsg;
- int error;
- XML_Parser parser;
-
- RecvUserDataCb_t RecvUserDataCb;
- RecvUserDataCb_t RecvGetUserDataCb;
- RecvServerInfoDataCb_t RecvServerInfoDataCb;
- RecvChgUserCb_t RecvChgUserCb;
- RecvCheckUserCb_t RecvCheckUserCb;
- RecvSendMessageCb_t RecvSendMessageCb;
-
- void * getUserDataDataCb;
- void * getUsersDataDataCb;
- void * getServerInfoDataCb;
- void * chgUserDataCb;
- void * checkUserDataCb;
- void * sendMessageDataCb;
-
- friend int AnsRecv(void * data, std::list<std::string> * list);
-};
-//-----------------------------------------------------------------------------
-
-#endif /* _SERVCONF_H_ */
-CXXFLAGS+=-g3 -Wall -W -Wextra -DLINUX -I../include -I../projects/stargazer -I../stglibs/stgconffiles.lib -I. -DUSE_ABSTRACT_SETTINGS
-LIBS=-lpthread
-PROG=tests
-
-SOURCES=main.cpp \
- test_raw_ip.cpp \
- test_admin_conf.cpp \
- test_tariff.cpp \
- test_conffiles.cpp \
- test_fee_charge_rules.cpp \
- test_reconnect_on_tariff_change.cpp \
- ../projects/stargazer/tariff_impl.cpp \
- ../projects/stargazer/user_impl.cpp \
- ../projects/stargazer/user_property.cpp \
- ../stglibs/conffiles.lib/conffiles.cpp \
- ../stglibs/common.lib/common.cpp \
- ../stglibs/logger.lib/logger.cpp \
- ../stglibs/scriptexecuter.lib/scriptexecuter.cpp
-
-.PHONY: all includes clean
-
-all: includes $(PROG)
-
-includes:
- make -C ../stglibs includes
-
-$(PROG): $(subst .cpp,.o,$(SOURCES))
+INCS = -I . \
+ -I ../include \
+ -I ../stglibs/common.lib/include \
+ -I ../stglibs/conffiles.lib/include \
+ -I ../stglibs/logger.lib/include \
+ -I ../stglibs/locker.lib/include \
+ -I ../stglibs/scriptexecuter.lib/include \
+ -I ../projects/stargazer
+DEFS = -DLINUX \
+ -DUSE_ABSTRACT_SETTINGS
+CFLAGS += -g3 -Wall -W -Wextra $(INCS) $(DEFS)
+CXXFLAGS = $(CFLAGS)
+LIBS = -lpthread
+PROG = tests
+
+SOURCES = main.cpp \
+ test_raw_ip.cpp \
+ test_admin_conf.cpp \
+ test_tariff.cpp \
+ test_conffiles.cpp \
+ test_fee_charge_rules.cpp \
+ test_reconnect_on_tariff_change.cpp \
+ ../projects/stargazer/tariff_impl.cpp \
+ ../projects/stargazer/user_impl.cpp \
+ ../projects/stargazer/user_property.cpp \
+ ../stglibs/conffiles.lib/conffiles.cpp \
+ ../stglibs/common.lib/common.cpp \
+ ../stglibs/logger.lib/logger.cpp \
+ ../stglibs/scriptexecuter.lib/scriptexecuter.cpp
+
+.PHONY: all clean
+
+all: $(PROG)
+
+$(PROG): $(addsuffix .o,$(basename $(SOURCES)))
$(CXX) $(LDFLAGS) $^ $(LIBS) -o $@
clean:
- rm -f *.o *.d $(PROG)
+ rm -f $(addsuffix .o,$(basename $(SOURCES))) $(addsuffix .d,$(SOURCES)) $(PROG)
ifneq ($(MAKECMDGOALS),distclean)
ifneq ($(MAKECMDGOALS),clean)
--include $(subst .cpp,.d,$(SOURCES))
+-include $(addsuffix .d,$(SOURCES))
endif
endif
-%.d: %.cpp
- @$(CC) -MM $(CXXFLAGS) $< > $@.$$$$; \
+%.cpp.d: %.cpp
+ @$(CXX) -MM $(CXXFLAGS) $< > $@.$$$$; \
+ sed 's,\($*\).o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
+ rm -f $@.$$$$
+
+%.c.d: %.c
+ @$(CC) -MM $(CFLAGS) $< > $@.$$$$; \
sed 's,\($*\).o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$
#include "tut/tut.hpp"
-#include "tut_reporter.h"
+#include "tut/tut_reporter.hpp"
namespace tut
{
{
struct priv_data {
enum {
- MIX2 = 0x06C6, // 2103210
- ONES = 0x1555,
- MIX3 = 0x1B1B, // 3210321
- TWOS = 0x2AAA,
- MIX1 = 0x24E4, // 0123012
- THREES = 0x3FFF
+ MIX2 = 0x0002C6C6, // 210321032
+ ONES = 0x00015555,
+ MIX3 = 0x00031B1B, // 321032103
+ TWOS = 0x0002AAAA,
+ MIX1 = 0x0000E4E4, // 012301230
+ THREES = 0x0003FFFF
};
};
ensure("zero.userAddDel == 0", zero.userAddDel == 0);
ensure("zero.adminChg == 0", zero.adminChg == 0);
ensure("zero.tariffChg == 0", zero.tariffChg == 0);
+ ensure("zero.serviceChg == 0", zero.serviceChg == 0);
+ ensure("zero.corpChg == 0", zero.corpChg == 0);
ensure("zero.ToInt() == 0", zero.ToInt() == 0);
}
template<>
void testobject::test<2>()
{
- set_test_name("Check uint16_t conversions");
+ set_test_name("Check uint32_t conversions");
- for (uint16_t i = 0; i < 4; ++i) {
+ for (uint8_t i = 0; i < 4; ++i) {
// 'i' is extra trash in high bits
- PRIV priv1(ONES | (i << 0x0E)); // All 1
+ PRIV priv1(ONES | (i << 0x12)); // All 1
ensure_equals("priv1.userStat == 1", priv1.userStat, 1);
ensure_equals("priv1.userConf == 1", priv1.userConf, 1);
ensure_equals("priv1.userAddDel == 1", priv1.userAddDel, 1);
ensure_equals("priv1.adminChg == 1", priv1.adminChg, 1);
ensure_equals("priv1.tariffChg == 1", priv1.tariffChg, 1);
+ ensure_equals("priv1.serviceChg == 1", priv1.serviceChg, 1);
+ ensure_equals("priv1.corpChg == 1", priv1.corpChg, 1);
- ensure_equals("priv1.ToInt() == 0x1555", priv1.ToInt(), static_cast<uint16_t>(ONES));
+ ensure_equals("priv1.ToInt() == 0x00015555", priv1.ToInt(), static_cast<uint32_t>(ONES));
- PRIV priv2(TWOS | (i << 0x0E)); // All 2
+ PRIV priv2(TWOS | (i << 0x12)); // All 2
ensure_equals("priv2.userStat == 2", priv2.userStat, 2);
ensure_equals("priv2.userConf == 2", priv2.userConf, 2);
ensure_equals("priv2.userAddDel == 2", priv2.userAddDel, 2);
ensure_equals("priv2.adminChg == 2", priv2.adminChg, 2);
ensure_equals("priv2.tariffChg == 2", priv2.tariffChg, 2);
+ ensure_equals("priv2.serviceChg == 2", priv2.serviceChg, 2);
+ ensure_equals("priv2.corpChg == 2", priv2.corpChg, 2);
- ensure_equals("priv2.ToInt() = 0x2AAA", priv2.ToInt(), static_cast<uint16_t>(TWOS));
+ ensure_equals("priv2.ToInt() = 0x0002AAAA", priv2.ToInt(), static_cast<uint32_t>(TWOS));
- PRIV priv3(THREES | (i << 0x0E)); // All 3
+ PRIV priv3(THREES | (i << 0x12)); // All 3
ensure_equals("priv3.userStat == 3", priv3.userStat, 3);
ensure_equals("priv3.userConf == 3", priv3.userConf, 3);
ensure_equals("priv3.userAddDel == 3", priv3.userAddDel, 3);
ensure_equals("priv3.adminChg == 3", priv3.adminChg, 3);
ensure_equals("priv3.tariffChg == 3", priv3.tariffChg, 3);
+ ensure_equals("priv3.serviceChg == 3", priv3.serviceChg, 3);
+ ensure_equals("priv3.corpChg == 3", priv3.corpChg, 3);
- ensure_equals("priv2.ToInt() = 0x3FFF", priv3.ToInt(), static_cast<uint16_t>(THREES));
+ ensure_equals("priv3.ToInt() = 0x0003FFFF", priv3.ToInt(), static_cast<uint32_t>(THREES));
- PRIV pm1(MIX1 | (i << 0x0E)); // 0123012
+ PRIV pm1(MIX1 | (i << 0x12)); // 012301230
ensure_equals("pm1.userStat == 0", pm1.userStat, 0);
ensure_equals("pm1.userConf == 1", pm1.userConf, 1);
ensure_equals("pm1.userAddDel == 0", pm1.userAddDel, 0);
ensure_equals("pm1.adminChg == 1", pm1.adminChg, 1);
ensure_equals("pm1.tariffChg == 2", pm1.tariffChg, 2);
+ ensure_equals("pm1.serviceChg == 3", pm1.serviceChg, 3);
+ ensure_equals("pm1.corpChg == 0", pm1.corpChg, 0);
- ensure_equals("pm1.ToInt() = 0x24E4", pm1.ToInt(), static_cast<uint16_t>(MIX1));
+ ensure_equals("pm1.ToInt() = 0xE4E4", pm1.ToInt(), static_cast<uint32_t>(MIX1));
- PRIV pm2(MIX2 | (i << 0x0E)); // 0123012
+ PRIV pm2(MIX2 | (i << 0x12)); // 210321032
ensure_equals("pm2.userStat == 2", pm2.userStat, 2);
ensure_equals("pm2.userConf == 1", pm2.userConf, 1);
ensure_equals("pm2.userAddDel == 2", pm2.userAddDel, 2);
ensure_equals("pm2.adminChg == 1", pm2.adminChg, 1);
ensure_equals("pm2.tariffChg == 0", pm2.tariffChg, 0);
+ ensure_equals("pm2.serviceChg == 3", pm2.serviceChg, 3);
+ ensure_equals("pm2.corpChg == 2", pm2.corpChg, 2);
- ensure_equals("pm2.ToInt() = 0x06C6", pm2.ToInt(), static_cast<uint16_t>(MIX2));
+ ensure_equals("pm2.ToInt() = 0x0002C6C6", pm2.ToInt(), static_cast<uint32_t>(MIX2));
- PRIV pm3(MIX3 | (i << 0x0E)); // 3210321
+ PRIV pm3(MIX3 | (i << 0x12)); // 321032103
ensure_equals("pm3.userStat == 3", pm3.userStat, 3);
ensure_equals("pm3.userConf == 2", pm3.userConf, 2);
ensure_equals("pm3.userAddDel == 3", pm3.userAddDel, 3);
ensure_equals("pm3.adminChg == 2", pm3.adminChg, 2);
ensure_equals("pm3.tariffChg == 1", pm3.tariffChg, 1);
+ ensure_equals("pm3.serviceChg == 0", pm3.serviceChg, 0);
+ ensure_equals("pm3.corpChg == 3", pm3.corpChg, 3);
- ensure_equals("pm3.ToInt() = 0x1B1B", pm3.ToInt(), static_cast<uint16_t>(MIX3));
+ ensure_equals("pm3.ToInt() = 0x00031B1B", pm3.ToInt(), static_cast<uint32_t>(MIX3));
}
template<>
void testobject::test<3>()
{
- set_test_name("Check explicit uint16_t conversions");
+ set_test_name("Check explicit uint32_t conversions");
- for (uint16_t i = 0; i < 4; ++i) {
+ for (uint8_t i = 0; i < 4; ++i) {
// 'i' is extra trash in high bits
PRIV priv1;
- priv1.FromInt(ONES | (i << 0x0E)); // All 1
+ priv1.FromInt(ONES | (i << 0x12)); // All 1
+
ensure_equals("priv1.userStat == 1", priv1.userStat, 1);
ensure_equals("priv1.userConf == 1", priv1.userConf, 1);
ensure_equals("priv1.userAddDel == 1", priv1.userAddDel, 1);
ensure_equals("priv1.adminChg == 1", priv1.adminChg, 1);
ensure_equals("priv1.tariffChg == 1", priv1.tariffChg, 1);
+ ensure_equals("priv1.serviceChg == 1", priv1.serviceChg, 1);
+ ensure_equals("priv1.corpChg == 1", priv1.corpChg, 1);
- ensure_equals("priv1.ToInt() == 0x1555", priv1.ToInt(), static_cast<uint16_t>(ONES));
+ ensure_equals("priv1.ToInt() == 0x00015555", priv1.ToInt(), static_cast<uint32_t>(ONES));
PRIV priv2;
- priv2.FromInt(TWOS | (i << 0x0E)); // All 2
+ priv2.FromInt(TWOS | (i << 0x12)); // All 2
ensure_equals("priv2.userStat == 2", priv2.userStat, 2);
ensure_equals("priv2.userConf == 2", priv2.userConf, 2);
ensure_equals("priv2.userAddDel == 2", priv2.userAddDel, 2);
ensure_equals("priv2.adminChg == 2", priv2.adminChg, 2);
ensure_equals("priv2.tariffChg == 2", priv2.tariffChg, 2);
+ ensure_equals("priv2.serviceChg == 2", priv2.serviceChg, 2);
+ ensure_equals("priv2.corpChg == 2", priv2.corpChg, 2);
- ensure_equals("priv2.ToInt() = 0x2AAA", priv2.ToInt(), static_cast<uint16_t>(TWOS));
+ ensure_equals("priv2.ToInt() = 0x0002AAAA", priv2.ToInt(), static_cast<uint32_t>(TWOS));
PRIV priv3;
- priv3.FromInt(THREES | (i << 0x0E)); // All 3
+ priv3.FromInt(THREES | (i << 0x12)); // All 3
ensure_equals("priv3.userStat == 3", priv3.userStat, 3);
ensure_equals("priv3.userConf == 3", priv3.userConf, 3);
ensure_equals("priv3.userAddDel == 3", priv3.userAddDel, 3);
ensure_equals("priv3.adminChg == 3", priv3.adminChg, 3);
ensure_equals("priv3.tariffChg == 3", priv3.tariffChg, 3);
+ ensure_equals("priv3.serviceChg == 3", priv3.serviceChg, 3);
+ ensure_equals("priv3.corpChg == 3", priv3.corpChg, 3);
- ensure_equals("priv2.ToInt() = 0x3FFF", priv3.ToInt(), static_cast<uint16_t>(THREES));
+ ensure_equals("priv3.ToInt() = 0x0003FFFF", priv3.ToInt(), static_cast<uint32_t>(THREES));
PRIV pm1;
- pm1.FromInt(MIX1 | (i << 0x0E)); // 0123012
+ pm1.FromInt(MIX1 | (i << 0x12)); // 012301230
ensure_equals("pm1.userStat == 0", pm1.userStat, 0);
ensure_equals("pm1.userConf == 1", pm1.userConf, 1);
ensure_equals("pm1.userAddDel == 0", pm1.userAddDel, 0);
ensure_equals("pm1.adminChg == 1", pm1.adminChg, 1);
ensure_equals("pm1.tariffChg == 2", pm1.tariffChg, 2);
+ ensure_equals("pm1.serviceChg == 3", pm1.serviceChg, 3);
+ ensure_equals("pm1.corpChg == 0", pm1.corpChg, 0);
- ensure_equals("pm1.ToInt() = 0x24E4", pm1.ToInt(), static_cast<uint16_t>(MIX1));
+ ensure_equals("pm1.ToInt() = 0xE4E4", pm1.ToInt(), static_cast<uint32_t>(MIX1));
PRIV pm2;
- pm2.FromInt(MIX2 | (i << 0x0E)); // 0123012
+ pm2.FromInt(MIX2 | (i << 0x12)); // 210321032
ensure_equals("pm2.userStat == 2", pm2.userStat, 2);
ensure_equals("pm2.userConf == 1", pm2.userConf, 1);
ensure_equals("pm2.userAddDel == 2", pm2.userAddDel, 2);
ensure_equals("pm2.adminChg == 1", pm2.adminChg, 1);
ensure_equals("pm2.tariffChg == 0", pm2.tariffChg, 0);
+ ensure_equals("pm2.serviceChg == 3", pm2.serviceChg, 3);
+ ensure_equals("pm2.corpChg == 2", pm2.corpChg, 2);
- ensure_equals("pm2.ToInt() = 0x06C6", pm2.ToInt(), static_cast<uint16_t>(MIX2));
+ ensure_equals("pm2.ToInt() = 0x0002C6C6", pm2.ToInt(), static_cast<uint32_t>(MIX2));
PRIV pm3;
- pm3.FromInt(MIX3 | (i << 0x0E)); // 3210321
+ pm3.FromInt(MIX3 | (i << 0x12)); // 321032103
ensure_equals("pm3.userStat == 3", pm3.userStat, 3);
ensure_equals("pm3.userConf == 2", pm3.userConf, 2);
ensure_equals("pm3.userAddDel == 3", pm3.userAddDel, 3);
ensure_equals("pm3.adminChg == 2", pm3.adminChg, 2);
ensure_equals("pm3.tariffChg == 1", pm3.tariffChg, 1);
+ ensure_equals("pm3.serviceChg == 0", pm3.serviceChg, 0);
+ ensure_equals("pm3.corpChg == 3", pm3.corpChg, 3);
- ensure_equals("pm3.ToInt() = 0x1B1B", pm3.ToInt(), static_cast<uint16_t>(MIX3));
+ ensure_equals("pm3.ToInt() = 0x00031B1B", pm3.ToInt(), static_cast<uint32_t>(MIX3));
}
USER_PROPERTY<double> & cash(user.GetProperty().cash);
USER_PROPERTY<std::string> & tariffName(user.GetProperty().tariffName);
- ensure_equals("user.cash == 0", user.GetProperty().cash, 0);
+ ensure_equals("user.cash == 0 (initial value)", user.GetProperty().cash, 0);
cash = 100;
- ensure_equals("user.cash == 100", user.GetProperty().cash, 100);
+ ensure_equals("user.cash == 100 (explicitly set)", user.GetProperty().cash, 100);
tariffs.SetFee(50);
tariffName = "test";
- ensure_equals("user.tariffName == 'test'", user.GetProperty().tariffName.ConstData(), "test");
+ ensure_equals("user.tariffName == 'test' (explicitly set)", user.GetProperty().tariffName.ConstData(), "test");
user.ProcessDayFee();
- ensure_equals("user.cash == 50", user.GetProperty().cash, 50);
+ ensure_equals("user.cash == 50 (first fee charge)", user.GetProperty().cash, 50);
user.ProcessDayFee();
- ensure_equals("user.cash == 0", user.GetProperty().cash, 0);
+ ensure_equals("user.cash == 0 (second fee charge)", user.GetProperty().cash, 0);
user.ProcessDayFee();
- ensure_equals("user.cash == -50", user.GetProperty().cash, -50);
+ ensure_equals("user.cash == -50 (third fee charge)", user.GetProperty().cash, -50);
+ user.ProcessDayFee();
+ ensure_equals("user.cash == -100 (fourth fee charge)", user.GetProperty().cash, -100);
}
template<>
USER_IMPL user(&settings, &store, &tariffs, &admin, NULL);
USER_PROPERTY<double> & cash(user.GetProperty().cash);
+ USER_PROPERTY<double> & credit(user.GetProperty().credit);
USER_PROPERTY<std::string> & tariffName(user.GetProperty().tariffName);
- ensure_equals("user.cash == 0", user.GetProperty().cash, 0);
+ ensure_equals("user.cash == 0 (initial value)", user.GetProperty().cash, 0);
+ ensure_equals("user.credit == 0 (initial value)", user.GetProperty().credit, 0);
cash = 100;
- ensure_equals("user.cash == 100", user.GetProperty().cash, 100);
+ ensure_equals("user.cash == 100 (explicitly set)", user.GetProperty().cash, 100);
tariffs.SetFee(50);
tariffName = "test";
- ensure_equals("user.tariffName == 'test'", user.GetProperty().tariffName.ConstData(), "test");
+ ensure_equals("user.tariffName == 'test' (explicitly set)", user.GetProperty().tariffName.ConstData(), "test");
+ user.ProcessDayFee();
+ ensure_equals("user.cash == 50 (first fee charge)", user.GetProperty().cash, 50);
user.ProcessDayFee();
- ensure_equals("user.cash == 50", user.GetProperty().cash, 50);
+ ensure_equals("user.cash == 0 (second fee charge)", user.GetProperty().cash, 0);
user.ProcessDayFee();
- ensure_equals("user.cash == 0", user.GetProperty().cash, 0);
+ ensure_equals("user.cash == -50 (third fee charge)", user.GetProperty().cash, -50);
user.ProcessDayFee();
- ensure_equals("user.cash == 0", user.GetProperty().cash, 0);
+ ensure_equals("user.cash == -50 (not charging `cause value is negative)", user.GetProperty().cash, -50);
cash = 49;
- ensure_equals("user.cash == 49", user.GetProperty().cash, 49);
+ ensure_equals("user.cash == 49 (explicitly set)", user.GetProperty().cash, 49);
+ user.ProcessDayFee();
+ ensure_equals("user.cash == -1 (charge to negative value)", user.GetProperty().cash, -1);
+ user.ProcessDayFee();
+ ensure_equals("user.cash == -1 (not charging `cause value is negative)", user.GetProperty().cash, -1);
+ credit = 50;
+ ensure_equals("user.credit == 50 (explicitly set)", user.GetProperty().credit, 50);
user.ProcessDayFee();
- ensure_equals("user.cash == -1", user.GetProperty().cash, -1);
+ ensure_equals("user.cash == -51 (charging `cause value + credit gives us a positive value)", user.GetProperty().cash, -51);
+ user.ProcessDayFee();
+ ensure_equals("user.cash == -51 (not charging `cause credit now is not enoght)", user.GetProperty().cash, -51);
}
template<>
USER_IMPL user(&settings, &store, &tariffs, &admin, NULL);
USER_PROPERTY<double> & cash(user.GetProperty().cash);
+ USER_PROPERTY<double> & credit(user.GetProperty().credit);
USER_PROPERTY<std::string> & tariffName(user.GetProperty().tariffName);
- ensure_equals("user.cash == 0", user.GetProperty().cash, 0);
+ ensure_equals("user.cash == 0 (initial value)", user.GetProperty().cash, 0);
cash = 100;
- ensure_equals("user.cash == 100", user.GetProperty().cash, 100);
+ ensure_equals("user.cash == 100 (explicitly set)", user.GetProperty().cash, 100);
tariffs.SetFee(50);
tariffName = "test";
- ensure_equals("user.tariffName == 'test'", user.GetProperty().tariffName.ConstData(), "test");
+ ensure_equals("user.tariffName == 'test' (explicitly set)", user.GetProperty().tariffName.ConstData(), "test");
+ user.ProcessDayFee();
+ ensure_equals("user.cash == 50 (first fee charge)", user.GetProperty().cash, 50);
user.ProcessDayFee();
- ensure_equals("user.cash == 50", user.GetProperty().cash, 50);
+ ensure_equals("user.cash == 0 (second fee charge)", user.GetProperty().cash, 0);
user.ProcessDayFee();
- ensure_equals("user.cash == 50", user.GetProperty().cash, 50);
- tariffs.SetFee(49);
+ ensure_equals("user.cash == 0 (not charging `cause value is lower than fee)", user.GetProperty().cash, 0);
+ cash = 50;
+ ensure_equals("user.cash == 50 (explicitly set)", user.GetProperty().cash, 50);
+ tariffs.SetFee(51);
user.ProcessDayFee();
- ensure_equals("user.cash == 1", user.GetProperty().cash, 1);
+ ensure_equals("user.cash == 50 (not charging `cause value is lower than fee)", user.GetProperty().cash, 50);
cash = 0;
- ensure_equals("user.cash == 0", user.GetProperty().cash, 0);
+ ensure_equals("user.cash == 0 (explicitly set)", user.GetProperty().cash, 0);
+ credit = 51;
+ ensure_equals("user.credit == 51 (explicitly set)", user.GetProperty().credit, 51);
+ user.ProcessDayFee();
+ ensure_equals("user.cash == -51 (charging `cause value + credit gives us a value greater than fee)", user.GetProperty().cash, -51);
user.ProcessDayFee();
- ensure_equals("user.cash == 0", user.GetProperty().cash, 0);
+ ensure_equals("user.cash == -51 (not charging `cause credit now is not enought)", user.GetProperty().cash, -51);
}
}
#include "tut/tut.hpp"
+#include "stg/os_int.h"
#include "raw_ip_packet_old.h"
#include "stg/raw_ip_packet.h"
set_test_name("Check structure consistency");
RAW_PACKET rp;
- rp.header.ipHeader.ip_v = 4;
- rp.header.ipHeader.ip_hl = 5;
- rp.header.ipHeader.ip_tos = 0;
- rp.header.ipHeader.ip_len = htons(40); // 20 of header + 20 of data
- rp.header.ipHeader.ip_p = 6;
- rp.header.ipHeader.ip_src.s_addr = inet_addr("192.168.0.1");
- rp.header.ipHeader.ip_dst.s_addr = inet_addr("192.168.0.101");
- rp.header.sPort = htons(80);
- rp.header.dPort = htons(38546);
-
- ensure_equals("IP header size (explicitly)", sizeof(rp.header.ipHeader), 20);
+ rp.rawPacket.header.ipHeader.ip_v = 4;
+ rp.rawPacket.header.ipHeader.ip_hl = 5;
+ rp.rawPacket.header.ipHeader.ip_tos = 0;
+ rp.rawPacket.header.ipHeader.ip_len = htons(40); // 20 of header + 20 of data
+ rp.rawPacket.header.ipHeader.ip_p = 6;
+ rp.rawPacket.header.ipHeader.ip_src.s_addr = inet_addr("192.168.0.1");
+ rp.rawPacket.header.ipHeader.ip_dst.s_addr = inet_addr("192.168.0.101");
+ rp.rawPacket.header.sPort = htons(80);
+ rp.rawPacket.header.dPort = htons(38546);
+
+ ensure_equals("IP header size (explicitly)", sizeof(rp.rawPacket.header.ipHeader), static_cast<size_t>(20));
ensure_equals("IP version", rp.GetIPVersion(), 4);
ensure_equals("IP header size (with options)", rp.GetHeaderLen(), 20);
ensure_equals("Underlying protocol version", rp.GetProto(), 6);
- ensure_equals("Packet length", rp.GetLen(), 40);
+ ensure_equals("Packet length", rp.GetLen(), static_cast<uint32_t>(40));
ensure_equals("Source IP address", rp.GetSrcIP(), inet_addr("192.168.0.1"));
ensure_equals("Destination IP address", rp.GetDstIP(), inet_addr("192.168.0.101"));
ensure_equals("Source port number", rp.GetSrcPort(), 80);
genVector(buf);
memcpy(p1.pckt, buf, 68);
- memcpy(p2.pckt, buf, 68);
- memcpy(p3.pckt, buf, 68);
+ memcpy(p2.rawPacket.pckt, buf, 68);
+ memcpy(p3.rawPacket.pckt, buf, 68);
ensure_equals("IP versions", p1.GetIPVersion(), p2.GetIPVersion());
ensure_equals("IP headers length", p1.GetHeaderLen(), p2.GetHeaderLen());
{
stream.unsetf(std::ios::dec);
stream.setf(std::ios::hex);
- for (size_t i = 0; i < sizeof(p.pckt); ++i) {
- stream << static_cast<unsigned>(p.pckt[i]);
+ for (size_t i = 0; i < sizeof(p.rawPacket.pckt); ++i) {
+ stream << static_cast<unsigned>(p.rawPacket.pckt[i]);
}
stream.unsetf(std::ios::hex);
stream.setf(std::ios::dec);
user.AddConnectedAfterNotifier(&connectionNotifier);
- USER_PROPERTY<double> & cash(user.GetProperty().cash);
USER_PROPERTY<std::string> & tariffName(user.GetProperty().tariffName);
USER_PROPERTY<USER_IPS> & ips(user.GetProperty().ips);
ips = StrToIPS("*");
ensure_equals("user.connected = false", user.GetConnected(), false);
- ensure_equals("connects = 0", connectionNotifier.GetConnects(), 0);
- ensure_equals("disconnects = 0", connectionNotifier.GetDisconnects(), 0);
+ ensure_equals("connects = 0", connectionNotifier.GetConnects(), static_cast<size_t>(0));
+ ensure_equals("disconnects = 0", connectionNotifier.GetDisconnects(), static_cast<size_t>(0));
ensure_equals("user.tariffName == NO_TARIFF_NAME", user.GetProperty().tariffName.ConstData(), NO_TARIFF_NAME);
ensure_equals("user.authorised_by = true", user.IsAuthorizedBy(&auth), true);
ensure_equals("user.connected = true", user.GetConnected(), true);
- ensure_equals("connects = 1", connectionNotifier.GetConnects(), 1);
- ensure_equals("disconnects = 0", connectionNotifier.GetDisconnects(), 0);
+ ensure_equals("connects = 1", connectionNotifier.GetConnects(), static_cast<size_t>(1));
+ ensure_equals("disconnects = 0", connectionNotifier.GetDisconnects(), static_cast<size_t>(0));
tariffName = "test";
ensure_equals("user.tariffName == 'test'", user.GetProperty().tariffName.ConstData(), "test");
ensure_equals("user.authorised_by = true", user.IsAuthorizedBy(&auth), true);
ensure_equals("user.connected = true", user.GetConnected(), true);
- ensure_equals("connects = 1", connectionNotifier.GetConnects(), 1);
- ensure_equals("disconnects = 0", connectionNotifier.GetDisconnects(), 0);
+ ensure_equals("connects = 1", connectionNotifier.GetConnects(), static_cast<size_t>(1));
+ ensure_equals("disconnects = 0", connectionNotifier.GetDisconnects(), static_cast<size_t>(0));
}
user.AddConnectedAfterNotifier(&connectionNotifier);
- USER_PROPERTY<double> & cash(user.GetProperty().cash);
USER_PROPERTY<std::string> & tariffName(user.GetProperty().tariffName);
USER_PROPERTY<USER_IPS> & ips(user.GetProperty().ips);
ips = StrToIPS("*");
ensure_equals("user.connected = false", user.GetConnected(), false);
- ensure_equals("connects = 0", connectionNotifier.GetConnects(), 0);
- ensure_equals("disconnects = 0", connectionNotifier.GetDisconnects(), 0);
+ ensure_equals("connects = 0", connectionNotifier.GetConnects(), static_cast<size_t>(0));
+ ensure_equals("disconnects = 0", connectionNotifier.GetDisconnects(), static_cast<size_t>(0));
ensure_equals("user.tariffName == NO_TARIFF_NAME", user.GetProperty().tariffName.ConstData(), NO_TARIFF_NAME);
ensure_equals("user.authorised_by = true", user.IsAuthorizedBy(&auth), true);
ensure_equals("user.connected = true", user.GetConnected(), true);
- ensure_equals("connects = 1", connectionNotifier.GetConnects(), 1);
- ensure_equals("disconnects = 0", connectionNotifier.GetDisconnects(), 0);
+ ensure_equals("connects = 1", connectionNotifier.GetConnects(), static_cast<size_t>(1));
+ ensure_equals("disconnects = 0", connectionNotifier.GetDisconnects(), static_cast<size_t>(0));
tariffName = "test";
ensure_equals("user.tariffName == 'test'", user.GetProperty().tariffName.ConstData(), "test");
ensure_equals("user.authorised_by = true", user.IsAuthorizedBy(&auth), true);
ensure_equals("user.connected = true", user.GetConnected(), true);
- ensure_equals("connects = 2", connectionNotifier.GetConnects(), 2);
- ensure_equals("disconnects = 1", connectionNotifier.GetDisconnects(), 1);
+ ensure_equals("connects = 2", connectionNotifier.GetConnects(), static_cast<size_t>(2));
+ ensure_equals("disconnects = 1", connectionNotifier.GetDisconnects(), static_cast<size_t>(1));
}
}
public:
TEST_ADMIN() : priv(0xffFF), ip(0) {}
- ADMIN & operator=(const ADMIN &) { return *this; }
- ADMIN & operator=(const ADMIN_CONF &) { return *this; }
- bool operator==(const ADMIN & /*rhs*/) const { return true; }
- bool operator!=(const ADMIN & /*rhs*/) const { return false; }
- bool operator<(const ADMIN & /*rhs*/) const { return true; }
- bool operator<=(const ADMIN & /*rhs*/) const { return true; }
-
const std::string & GetPassword() const { return password; }
const std::string & GetLogin() const { return login; }
PRIV const * GetPriv() const { return &priv; }
int ReadTariffs () { return 0; }
const TARIFF * FindByName(const std::string & /*name*/) const { return &testTariff; }
const TARIFF * GetNoTariff() const { return NULL; }
- int GetTariffsNum() const { return 0; }
int Del(const std::string & /*name*/, const ADMIN * /*admin*/) { return 0; }
int Add(const std::string & /*name*/, const ADMIN * /*admin*/) { return 0; }
int Chg(const TARIFF_DATA & /*td*/, const ADMIN * /*admin*/) { return 0; }
+ void AddNotifierAdd(NOTIFIER_BASE<TARIFF_DATA> *) {}
+ void DelNotifierAdd(NOTIFIER_BASE<TARIFF_DATA> *) {}
+
+ void AddNotifierDel(NOTIFIER_BASE<TARIFF_DATA> *) {}
+ void DelNotifierDel(NOTIFIER_BASE<TARIFF_DATA> *) {}
+
void GetTariffsData(std::list<TARIFF_DATA> * /*tdl*/) {}
+ size_t Count() const { return 0; }
+
const std::string & GetStrError() const { return strError; }
void SetFee(double fee);
{ return 0; }
void Del(const std::string & /*login*/, const ADMIN * /*admin*/) {}
+ bool Authorize(const std::string &, uint32_t, uint32_t, const AUTH *)
+ { return false; }
+ bool Unauthorize(const std::string &, const AUTH *)
+ { return false; }
+
int ReadUsers() { return 0; }
- int GetUserNum() const { return 0; }
+ virtual size_t Count() const { return 0; };
int FindByIPIdx(uint32_t /*ip*/, USER_PTR * /*user*/) const
{ return -1; }
+++ /dev/null
-
-#include <tut/tut.hpp>
#ifndef TUT_H_GUARD
#define TUT_H_GUARD
+#include <tut/tut_config.hpp>
#include <iostream>
#include <map>
#include <sstream>
#include <iterator>
#include <algorithm>
-#include <typeinfo>
-
-#if defined(linux)
-#define TUT_USE_POSIX
-#endif
#include "tut_exception.hpp"
#include "tut_result.hpp"
namespace tut
{
+template <class, int>
+class test_group;
+
/**
* Test object. Contains data test run upon and default test method
* implementation. Inherited from Data to allow tests to
template <class Data>
class test_object : public Data, public test_object_posix
{
+ template<class D, int M>
+ friend class test_group;
+
+ void set_test_group(const char *group)
+ {
+ current_test_group_ = group;
+ }
+
+ void set_test_id(int current_test_id)
+ {
+ current_test_id_ = current_test_id;
+ }
+
public:
/**
* Default constructor
*/
test_object()
+ : called_method_was_a_dummy_test_(false),
+ current_test_id_(0),
+ current_test_name_(),
+ current_test_group_()
{
}
return current_test_name_;
}
- void set_test_id(int current_test_id)
+ const std::string& get_test_group() const
{
- current_test_id_ = current_test_id;
+ return current_test_group_;
}
int get_test_id() const
* Used to detect usused test numbers and avoid unnecessary
* test object creation which may be time-consuming depending
* on operations described in Data::Data() and Data::~Data().
- * TODO: replace with throwing special exception from default test.
*/
bool called_method_was_a_dummy_test_;
+ virtual ~test_object()
+ {
+ }
+
private:
int current_test_id_;
std::string current_test_name_;
+ std::string current_test_group_;
};
template <class Data, int MaxTestsInGroup = 50>
class test_group : public group_base, public test_group_posix
{
+ test_group(const test_group&);
+ void operator=(const test_group&);
+
const char* name_;
typedef void (test_object<Data>::*testmethod)();
tests tests_;
tests_iterator current_test_;
- enum seh_result
- {
- SEH_OK,
- SEH_CTOR,
- SEH_TEST,
- SEH_DUMMY
- };
+ enum seh_result
+ {
+ SEH_OK,
+#if defined(TUT_USE_SEH)
+ SEH_CTOR,
+ SEH_TEST,
+#endif
+ SEH_DUMMY
+ };
/**
* Exception-in-destructor-safe smart-pointer class.
{
try
{
+#if defined(TUT_USE_SEH)
if (delete_obj() == false)
{
throw warning("destructor of test object raised"
" an SEH exception");
}
+#else
+ bool d = delete_obj();
+ assert(d && "delete failed with SEH disabled: runtime bug?");
+#endif
}
catch (const std::exception& ex)
{
* Creates and registers test group with specified name.
*/
test_group(const char* name)
- : name_(name)
+ : name_(name),
+ tests_(),
+ current_test_()
{
// register itself
runner.get().register_group(name_,this);
* This constructor is used in self-test run only.
*/
test_group(const char* name, test_runner& another_runner)
- : name_(name)
+ : name_(name),
+ tests_(),
+ current_test_()
{
// register itself
another_runner.register_group(name_, this);
try
{
switch (run_test_seh_(ti->second, obj, current_test_name, ti->first))
- {
- case SEH_CTOR:
- throw bad_ctor("seh");
- break;
-
- case SEH_TEST:
- throw seh("seh");
- break;
-
- case SEH_DUMMY:
- tr.result = test_result::dummy;
- break;
-
- case SEH_OK:
- // ok
- break;
+ {
+#if defined(TUT_USE_SEH)
+ case SEH_CTOR:
+ throw bad_ctor("seh");
+ break;
+
+ case SEH_TEST:
+ throw seh("seh");
+ break;
+#endif
+ case SEH_DUMMY:
+ tr.result = test_result::dummy;
+ break;
+
+ case SEH_OK:
+ // ok
+ break;
}
}
catch (const rethrown& ex)
catch (const tut_error& ex)
{
tr.result = ex.result();
- tr.exception_typeid = typeid(ex).name();
+ tr.exception_typeid = ex.type();
tr.message = ex.what();
}
catch (const std::exception& ex)
{
tr.result = test_result::ex;
- tr.exception_typeid = typeid(ex).name();
+ tr.exception_typeid = type_name(ex);
tr.message = ex.what();
}
catch (...)
__try
{
#endif
- if (obj.get() == 0)
- {
- reset_holder_(obj);
- }
+ if (obj.get() == 0)
+ {
+ reset_holder_(obj);
+ }
- obj->called_method_was_a_dummy_test_ = false;
+ obj->called_method_was_a_dummy_test_ = false;
#if defined(TUT_USE_SEH)
{
#endif
obj.get()->set_test_id(current_test_id);
+ obj.get()->set_test_group(name_);
(obj.get()->*tm)();
#if defined(TUT_USE_SEH)
}
}
#endif
- if (obj->called_method_was_a_dummy_test_)
- {
- // do not call obj.release(); reuse object
- return SEH_DUMMY;
- }
+ if (obj->called_method_was_a_dummy_test_)
+ {
+ // do not call obj.release(); reuse object
+ return SEH_DUMMY;
+ }
- current_test_name = obj->get_test_name();
- obj.permit_throw();
- obj.release();
+ current_test_name = obj->get_test_name();
+ obj.permit_throw();
+ obj.release();
#if defined(TUT_USE_SEH)
}
__except(handle_seh_(::GetExceptionCode()))
{
- return SEH_CTOR;
+ return SEH_CTOR;
}
#endif
return SEH_OK;
#endif
}
-#endif
+#endif // TUT_H_GUARD
#ifndef TUT_ASSERT_H_GUARD
#define TUT_ASSERT_H_GUARD
+#include <tut/tut_config.hpp>
-#include "tut_exception.hpp"
#include <limits>
#include <iomanip>
+#include <iterator>
+#include <cassert>
+#include <cmath>
#if defined(TUT_USE_POSIX)
#include <errno.h>
#include <cstring>
#endif
+#include "tut_exception.hpp"
+
namespace tut
{
namespace detail
{
template<typename M>
- std::ostream &msg_prefix(std::ostream &str, const M &msg)
+ std::ostringstream &msg_prefix(std::ostringstream &str, const M &msg)
{
- std::stringstream ss;
+ std::ostringstream ss;
ss << msg;
if(!ss.str().empty())
{
- str << ss.rdbuf() << ": ";
+ str << msg << ": ";
}
return str;
* Tests two objects for being equal.
* Throws if false.
*
- * NB: both T and Q must have operator << defined somewhere, or
+ * NB: both LHS and RHS must have operator << defined somewhere, or
* client code will not compile at all!
*/
template <typename M, typename LHS, typename RHS>
{
if (expected != actual)
{
- std::stringstream ss;
+ std::ostringstream ss;
detail::msg_prefix(ss,msg)
- << "expected '"
+ << "expected `"
<< expected
- << "' actual '"
+ << "` actual `"
<< actual
- << '\'';
+ << "`";
throw failure(ss.str());
}
}
-template <typename LHS, typename RHS>
-void ensure_equals(const LHS& actual, const RHS& expected)
+/**
+ * Tests two pointers for being equal.
+ * Throws if false.
+ *
+ * NB: both T and Q must have operator << defined somewhere, or
+ * client code will not compile at all!
+ */
+template <typename M, typename LHS, typename RHS>
+void ensure_equals(const M& msg, const LHS * const actual, const RHS * const expected)
{
- ensure_equals("Values are not equal", actual, expected);
+ if (expected != actual)
+ {
+ std::ostringstream ss;
+ detail::msg_prefix(ss,msg)
+ << "expected `"
+ << (void*)expected
+ << "` actual `"
+ << (void*)actual
+ << "`";
+ throw failure(ss.str());
+ }
}
template<typename M>
-void ensure_equals(const M& msg, const double& actual, const double& expected,
- const double& epsilon = std::numeric_limits<double>::epsilon())
+void ensure_equals(const M& msg, const double& actual, const double& expected, const double& epsilon)
{
const double diff = actual - expected;
- if ( !((diff <= epsilon) && (diff >= -epsilon )) )
+ if ( (actual != expected) && !((diff <= epsilon) && (diff >= -epsilon )) )
{
- std::stringstream ss;
+ std::ostringstream ss;
detail::msg_prefix(ss,msg)
<< std::scientific
<< std::showpoint
<< std::setprecision(16)
- << "expected " << expected
- << " actual " << actual
- << " with precision " << epsilon;
+ << "expected `" << expected
+ << "` actual `" << actual
+ << "` with precision `" << epsilon << "`";
throw failure(ss.str());
}
}
+
+template<typename M>
+void ensure_equals(const M& msg, const double& actual, const double& expected)
+{
+ ensure_equals(msg, actual, expected, std::numeric_limits<double>::epsilon());
+}
+
+template <typename LHS, typename RHS>
+void ensure_equals(const LHS& actual, const RHS& expected)
+{
+ ensure_equals("Values are not equal", actual, expected);
+}
+
+
+template<typename LhsIterator, typename RhsIterator>
+void ensure_equals(const std::string &msg,
+ const LhsIterator &lhs_begin, const LhsIterator &lhs_end,
+ const RhsIterator &rhs_begin, const RhsIterator &rhs_end)
+{
+ typename std::iterator_traits<LhsIterator>::difference_type lhs_size = std::distance(lhs_begin, lhs_end);
+ typename std::iterator_traits<RhsIterator>::difference_type rhs_size = std::distance(rhs_begin, rhs_end);
+
+ if(lhs_size < rhs_size)
+ {
+ ensure_equals(msg + ": range is too short", lhs_size, rhs_size);
+ }
+
+ if(lhs_size > rhs_size)
+ {
+ ensure_equals(msg + ": range is too long", lhs_size, rhs_size);
+ }
+
+ assert(lhs_size == rhs_size);
+
+ LhsIterator lhs_i = lhs_begin;
+ RhsIterator rhs_i = rhs_begin;
+ while( (lhs_i != lhs_end) && (rhs_i != rhs_end) )
+ {
+ if(*lhs_i != *rhs_i)
+ {
+ std::ostringstream ss;
+ detail::msg_prefix(ss,msg)
+ << "expected `" << *rhs_i
+ << "` actual `" << *lhs_i
+ << "` at offset " << std::distance(lhs_begin, lhs_i);
+ throw failure(ss.str());
+ }
+
+ lhs_i++;
+ rhs_i++;
+ }
+
+ assert(lhs_i == lhs_end);
+ assert(rhs_i == rhs_end);
+}
+
+template<typename LhsIterator, typename RhsIterator>
+void ensure_equals(const LhsIterator &lhs_begin, const LhsIterator &lhs_end,
+ const RhsIterator &rhs_begin, const RhsIterator &rhs_end)
+{
+ ensure_equals("Ranges are not equal", lhs_begin, lhs_end, rhs_begin, rhs_end);
+}
+
+template<typename LhsType, typename RhsType>
+void ensure_equals(const LhsType *lhs_begin, const LhsType *lhs_end,
+ const RhsType *rhs_begin, const RhsType *rhs_end)
+{
+ ensure_equals("Ranges are not equal", lhs_begin, lhs_end, rhs_begin, rhs_end);
+}
+
/**
* Tests two objects for being at most in given distance one from another.
* Borders are excluded.
{
if (expected-distance >= actual || expected+distance <= actual)
{
- std::stringstream ss;
+ std::ostringstream ss;
detail::msg_prefix(ss,msg)
- << " expected ("
+ << " expected `"
<< expected-distance
- << " - "
+ << "` - `"
<< expected+distance
- << ") actual '"
+ << "` actual `"
<< actual
- << '\'';
+ << "`";
throw failure(ss.str());
}
}
{
#if defined(TUT_USE_POSIX)
char e[512];
- std::stringstream ss;
+ std::ostringstream ss;
detail::msg_prefix(ss,msg)
<< strerror_r(errno, e, sizeof(e));
throw failure(ss.str());
throw failure(msg);
}
+/**
+ * Mark test case as known failure and skip execution.
+ */
+void skip(const char* msg = "")
+{
+ throw skipped(msg);
+}
+
+template<typename M>
+void skip(const M& msg)
+{
+ throw skipped(msg);
+}
+
} // end of namespace
}
--- /dev/null
+#ifndef TUT_CONFIG_H_GUARD
+#define TUT_CONFIG_H_GUARD
+
+#define TUT_USE_RTTI 1
+
+#endif
#ifndef TUT_CONSOLE_REPORTER
#define TUT_CONSOLE_REPORTER
-
#include <tut/tut.hpp>
#include <cassert>
{
switch(tr.result)
{
- case tut::test_result::ok:
- os << '.';
- break;
- case tut::test_result::fail:
- os << '[' << tr.test << "=F]";
- break;
- case tut::test_result::ex_ctor:
- os << '[' << tr.test << "=C]";
- break;
- case tut::test_result::ex:
- os << '[' << tr.test << "=X]";
- break;
- case tut::test_result::warn:
- os << '[' << tr.test << "=W]";
- break;
- case tut::test_result::term:
- os << '[' << tr.test << "=T]";
- break;
- case tut::test_result::rethrown:
- os << '[' << tr.test << "=P]";
- break;
- case tut::test_result::dummy:
- assert(!"Should never be called");
+ case tut::test_result::ok:
+ os << '.';
+ break;
+ case tut::test_result::fail:
+ os << '[' << tr.test << "=F]";
+ break;
+ case tut::test_result::ex_ctor:
+ os << '[' << tr.test << "=C]";
+ break;
+ case tut::test_result::ex:
+ os << '[' << tr.test << "=X]";
+ break;
+ case tut::test_result::warn:
+ os << '[' << tr.test << "=W]";
+ break;
+ case tut::test_result::term:
+ os << '[' << tr.test << "=T]";
+ break;
+ case tut::test_result::rethrown:
+ os << '[' << tr.test << "=P]";
+ break;
+ case tut::test_result::skipped:
+ os << '[' << tr.test << "=S]";
+ break;
+ case tut::test_result::dummy:
+ throw tut::tut_error("console reporter called for dummy test result");
}
return os;
not_passed_list not_passed;
std::ostream& os;
+ console_reporter(const console_reporter &);
+ console_reporter &operator=(const console_reporter &);
public:
int ok_count;
int failures_count;
int terminations_count;
int warnings_count;
+ int skipped_count;
console_reporter()
- : os(std::cout)
+ : current_group(),
+ not_passed(),
+ os(std::cout),
+ ok_count(0),
+ exceptions_count(0),
+ failures_count(0),
+ terminations_count(0),
+ warnings_count(0),
+ skipped_count(0)
{
init();
}
console_reporter(std::ostream& out)
- : os(out)
+ : current_group(),
+ not_passed(),
+ os(out),
+ ok_count(0),
+ exceptions_count(0),
+ failures_count(0),
+ terminations_count(0),
+ warnings_count(0),
+ skipped_count(0)
+
{
init();
}
case test_result::term:
terminations_count++;
break;
+ case test_result::skipped:
+ skipped_count++;
+ break;
case tut::test_result::dummy:
- assert(!"Should never be called");
+ assert( (tr.result != tut::test_result::dummy) && "Should never be called");
} // switch
- if (tr.result != tut::test_result::ok)
+ if ( (tr.result != tut::test_result::ok) &&
+ (tr.result != tut::test_result::skipped) )
{
not_passed.push_back(tr);
}
{
if (tr.result == test_result::fail)
{
- os << " failed assertion: \"" << tr.message << "\""
+ os << " failed assertion: `" << tr.message << "`"
<< std::endl;
}
else
{
- os << " message: \"" << tr.message << "\""
+ os << " message: `" << tr.message << "`"
<< std::endl;
}
}
{
os << " warnings:" << warnings_count;
}
+
os << " ok:" << ok_count;
+
+ if(skipped_count > 0)
+ {
+ os << " skipped:" << skipped_count;
+ }
os << std::endl;
}
- bool all_ok() const
+ virtual bool all_ok() const
{
return not_passed.empty();
}
failures_count = 0;
terminations_count = 0;
warnings_count = 0;
+ skipped_count = 0;
not_passed.clear();
}
};
#include <fstream>\r
#include <vector>\r
#include <stdexcept>\r
+#include <memory>\r
\r
namespace tut\r
{\r
*/\r
class cppunit_reporter : public tut::callback\r
{\r
- private:\r
- std::vector<tut::test_result> failed_tests;\r
- std::vector<tut::test_result> passed_tests;\r
- std::string filename;\r
+ std::vector<tut::test_result> failed_tests_;\r
+ std::vector<tut::test_result> passed_tests_;\r
+ const std::string filename_;\r
+ std::auto_ptr<std::ostream> stream_;\r
\r
- std::string encode(const std::string & text)\r
- {\r
- std::string out;\r
\r
- for (unsigned int i=0; i<text.length(); ++i) {\r
- char c = text[i];\r
- switch (c) {\r
- case '<':\r
- out += "<";\r
- break;\r
- case '>':\r
- out += ">";\r
- break;\r
- case '&':\r
- out += "&";\r
- break;\r
- case '\'':\r
- out += "'";\r
- break;\r
- case '"':\r
- out += """;\r
- break;\r
- default:\r
- out += c;\r
- }\r
- }\r
-\r
- return out;\r
- }\r
+ cppunit_reporter(const cppunit_reporter &);\r
+ cppunit_reporter &operator=(const cppunit_reporter &);\r
\r
public:\r
+ explicit cppunit_reporter(const std::string &filename = "testResult.xml")\r
+ : failed_tests_(),\r
+ passed_tests_(),\r
+ filename_(filename),\r
+ stream_(new std::ofstream(filename_.c_str()))\r
+ {\r
+ if (!stream_->good()) {\r
+ throw tut_error("Cannot open output file `" + filename_ + "`");\r
+ }\r
+ }\r
\r
- cppunit_reporter(const std::string & _filename = "")\r
+ explicit cppunit_reporter(std::ostream &stream)\r
+ : failed_tests_(),\r
+ passed_tests_(),\r
+ filename_(),\r
+ stream_(&stream)\r
{\r
- setFilename(_filename);\r
}\r
\r
- void setFilename(const std::string & _filename)\r
+ ~cppunit_reporter()\r
{\r
- if (_filename == "")\r
- {\r
- filename = "testResult.xml";\r
- }\r
- else\r
+ if(filename_.empty())\r
{\r
- filename = _filename;\r
+ stream_.release();\r
}\r
}\r
\r
void run_started()\r
{\r
- failed_tests.clear();\r
- passed_tests.clear();\r
+ failed_tests_.clear();\r
+ passed_tests_.clear();\r
}\r
\r
void test_completed(const tut::test_result& tr)\r
{\r
- if (tr.result == test_result::ok) {\r
- passed_tests.push_back(tr);\r
- } else {\r
- failed_tests.push_back(tr);\r
+ assert(tr.result != test_result::dummy );\r
+ if ( (tr.result == test_result::ok) ||\r
+ (tr.result == test_result::skipped) )\r
+ {\r
+ passed_tests_.push_back(tr);\r
+ }\r
+ else\r
+ {\r
+ failed_tests_.push_back(tr);\r
}\r
}\r
\r
int failures = 0;\r
std::string failure_type;\r
std::string failure_msg;\r
- std::ofstream xmlfile;\r
-\r
- xmlfile.open(filename.c_str(), std::ios::in | std::ios::trunc);\r
- if (!xmlfile.is_open()) {\r
- throw (std::runtime_error("Cannot open file for output"));\r
- }\r
\r
- /* *********************** header ***************************** */\r
- xmlfile << "<?xml version=\"1.0\" encoding='ISO-8859-1' standalone='yes' ?>" << std::endl\r
- << "<TestRun>" << std::endl;\r
+ *stream_ << "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\" ?>" << std::endl\r
+ << "<TestRun>" << std::endl;\r
\r
- /* *********************** failed tests ***************************** */\r
- if (failed_tests.size() > 0) {\r
- xmlfile << " <FailedTests>" << std::endl;\r
+ if (failed_tests_.size() > 0)\r
+ {\r
+ *stream_ << " <FailedTests>" << std::endl;\r
\r
- for (unsigned int i=0; i<failed_tests.size(); i++) {\r
- switch (failed_tests[i].result) {\r
+ for (unsigned int i=0; i<failed_tests_.size(); i++)\r
+ {\r
+ switch (failed_tests_[i].result)\r
+ {\r
case test_result::fail:\r
failure_type = "Assertion";\r
failure_msg = "";\r
break;\r
case test_result::ex:\r
failure_type = "Assertion";\r
- failure_msg = "Thrown exception: " + failed_tests[i].exception_typeid + '\n';\r
+ failure_msg = "Thrown exception: " + failed_tests_[i].exception_typeid + '\n';\r
failures++;\r
break;\r
case test_result::warn:\r
failure_type = "Assertion";\r
- failure_msg = "Destructor failed.\n";\r
+ failure_msg = "Destructor failed\n";\r
failures++;\r
break;\r
case test_result::term:\r
failure_type = "Error";\r
- failure_msg = "Test application terminated abnormally.\n";\r
+ failure_msg = "Test application terminated abnormally\n";\r
errors++;\r
break;\r
case test_result::ex_ctor:\r
failure_type = "Error";\r
- failure_msg = "Constructor has thrown an exception: " + failed_tests[i].exception_typeid + '\n';\r
+ failure_msg = "Constructor has thrown an exception: " + failed_tests_[i].exception_typeid + '\n';\r
errors++;\r
break;\r
case test_result::rethrown:\r
failure_type = "Assertion";\r
- failure_msg = "Child failed";\r
+ failure_msg = "Child failed\n";\r
failures++;\r
break;\r
- default:\r
+ default: // ok, skipped, dummy\r
failure_type = "Error";\r
failure_msg = "Unknown test status, this should have never happened. "\r
- "You may just have found a BUG in TUT CppUnit reporter, please report it immediately.\n";\r
+ "You may just have found a bug in TUT, please report it immediately.\n";\r
errors++;\r
break;\r
}\r
\r
- xmlfile << " <FailedTest id=\"" << failed_tests[i].test << "\">" << std::endl\r
- << " <Name>" << encode(failed_tests[i].group) + "::" + encode(failed_tests[i].name) << "</Name>" << std::endl\r
- << " <FailureType>" << failure_type << "</FailureType>" << std::endl\r
- << " <Location>" << std::endl\r
- << " <File>Unknown</File>" << std::endl\r
- << " <Line>Unknown</Line>" << std::endl\r
- << " </Location>" << std::endl\r
- << " <Message>" << encode(failure_msg + failed_tests[i].message) << "</Message>" << std::endl\r
- << " </FailedTest>" << std::endl;\r
+ *stream_ << " <FailedTest id=\"" << failed_tests_[i].test << "\">" << std::endl\r
+ << " <Name>" << encode(failed_tests_[i].group) + "::" + encode(failed_tests_[i].name) << "</Name>" << std::endl\r
+ << " <FailureType>" << failure_type << "</FailureType>" << std::endl\r
+ << " <Location>" << std::endl\r
+ << " <File>Unknown</File>" << std::endl\r
+ << " <Line>Unknown</Line>" << std::endl\r
+ << " </Location>" << std::endl\r
+ << " <Message>" << encode(failure_msg + failed_tests_[i].message) << "</Message>" << std::endl\r
+ << " </FailedTest>" << std::endl;\r
}\r
\r
- xmlfile << " </FailedTests>" << std::endl;\r
+ *stream_ << " </FailedTests>" << std::endl;\r
}\r
\r
/* *********************** passed tests ***************************** */\r
- if (passed_tests.size() > 0) {\r
- xmlfile << " <SuccessfulTests>" << std::endl;\r
-\r
- for (unsigned int i=0; i<passed_tests.size(); i++) {\r
- xmlfile << " <Test id=\"" << passed_tests[i].test << "\">" << std::endl\r
- << " <Name>" << encode(passed_tests[i].group) + "::" + encode(passed_tests[i].name) << "</Name>" << std::endl\r
- << " </Test>" << std::endl;\r
+ if (passed_tests_.size() > 0) {\r
+ *stream_ << " <SuccessfulTests>" << std::endl;\r
+\r
+ for (unsigned int i=0; i<passed_tests_.size(); i++)\r
+ {\r
+ *stream_ << " <Test id=\"" << passed_tests_[i].test << "\">" << std::endl\r
+ << " <Name>" << encode(passed_tests_[i].group) + "::" + encode(passed_tests_[i].name) << "</Name>" << std::endl\r
+ << " </Test>" << std::endl;\r
}\r
\r
- xmlfile << " </SuccessfulTests>" << std::endl;\r
+ *stream_ << " </SuccessfulTests>" << std::endl;\r
}\r
\r
/* *********************** statistics ***************************** */\r
- xmlfile << " <Statistics>" << std::endl\r
- << " <Tests>" << (failed_tests.size() + passed_tests.size()) << "</Tests>" << std::endl\r
- << " <FailuresTotal>" << failed_tests.size() << "</FailuresTotal>" << std::endl\r
- << " <Errors>" << errors << "</Errors>" << std::endl\r
- << " <Failures>" << failures << "</Failures>" << std::endl\r
- << " </Statistics>" << std::endl;\r
+ *stream_ << " <Statistics>" << std::endl\r
+ << " <Tests>" << (failed_tests_.size() + passed_tests_.size()) << "</Tests>" << std::endl\r
+ << " <FailuresTotal>" << failed_tests_.size() << "</FailuresTotal>" << std::endl\r
+ << " <Errors>" << errors << "</Errors>" << std::endl\r
+ << " <Failures>" << failures << "</Failures>" << std::endl\r
+ << " </Statistics>" << std::endl;\r
\r
/* *********************** footer ***************************** */\r
- xmlfile << "</TestRun>" << std::endl;\r
-\r
- xmlfile.close();\r
+ *stream_ << "</TestRun>" << std::endl;\r
}\r
\r
- bool all_ok() const\r
+ virtual bool all_ok() const\r
{\r
- return failed_tests.empty();\r
- };\r
+ return failed_tests_.empty();\r
+ }\r
\r
+ /**\r
+ * \brief Encodes text to XML\r
+ * XML-reserved characters (e.g. "<") are encoded according to specification\r
+ * @param text text to be encoded\r
+ * @return encoded string\r
+ */\r
+ static std::string encode(const std::string & text)\r
+ {\r
+ std::string out;\r
+\r
+ for (unsigned int i=0; i<text.length(); ++i) {\r
+ char c = text[i];\r
+ switch (c) {\r
+ case '<':\r
+ out += "<";\r
+ break;\r
+ case '>':\r
+ out += ">";\r
+ break;\r
+ case '&':\r
+ out += "&";\r
+ break;\r
+ case '\'':\r
+ out += "'";\r
+ break;\r
+ case '"':\r
+ out += """;\r
+ break;\r
+ default:\r
+ out += c;\r
+ }\r
+ }\r
\r
+ return out;\r
+ }\r
};\r
\r
}\r
*/
struct tut_error : public std::exception
{
- tut_error(const std::string& msg)
+ explicit tut_error(const std::string& msg)
: err_msg(msg)
{
}
return test_result::ex;
}
+ virtual std::string type() const
+ {
+ return "tut::tut_error";
+ }
+
const char* what() const throw()
{
return err_msg.c_str();
}
private:
+ void operator=(const tut_error &);
- std::string err_msg;
+ const std::string err_msg;
};
/**
*/
struct no_such_group : public tut_error
{
- no_such_group(const std::string& grp)
+ explicit no_such_group(const std::string& grp)
: tut_error(grp)
{
}
+ virtual std::string type() const
+ {
+ return "tut::no_such_group";
+ }
+
~no_such_group() throw()
{
}
};
+/**
+ * Test not found exception.
+ */
+struct no_such_test : public tut_error
+{
+ explicit no_such_test(const std::string& grp)
+ : tut_error(grp)
+ {
+ }
+
+ virtual std::string type() const
+ {
+ return "tut::no_such_test";
+ }
+
+ ~no_such_test() throw()
+ {
+ }
+};
+
/**
* Internal exception to be throwed when
* test constructor has failed.
*/
struct bad_ctor : public tut_error
{
- bad_ctor(const std::string& msg)
+ explicit bad_ctor(const std::string& msg)
: tut_error(msg)
{
}
return test_result::ex_ctor;
}
+ virtual std::string type() const
+ {
+ return "tut::bad_ctor";
+ }
+
~bad_ctor() throw()
{
}
*/
struct failure : public tut_error
{
- failure(const std::string& msg)
+ explicit failure(const std::string& msg)
: tut_error(msg)
{
}
return test_result::fail;
}
+ virtual std::string type() const
+ {
+ return "tut::failure";
+ }
+
~failure() throw()
{
}
*/
struct warning : public tut_error
{
- warning(const std::string& msg)
+ explicit warning(const std::string& msg)
: tut_error(msg)
{
}
return test_result::warn;
}
+ virtual std::string type() const
+ {
+ return "tut::warning";
+ }
+
~warning() throw()
{
}
*/
struct seh : public tut_error
{
- seh(const std::string& msg)
+ explicit seh(const std::string& msg)
: tut_error(msg)
{
}
return test_result::term;
}
+ virtual std::string type() const
+ {
+ return "tut::seh";
+ }
+
~seh() throw()
{
}
return test_result::rethrown;
}
+ virtual std::string type() const
+ {
+ return "tut::rethrown";
+ }
+
~rethrown() throw()
{
}
const test_result tr;
};
+struct skipped : public tut_error
+{
+ explicit skipped(const std::string& msg)
+ : tut_error(msg)
+ {
+ }
+
+ virtual test_result::result_type result() const
+ {
+ return test_result::skipped;
+ }
+
+ virtual std::string type() const
+ {
+ return "tut::skipped";
+ }
+
+ ~skipped() throw()
+ {
+ }
+};
+
}
#endif
--- /dev/null
+/**
+ * @brief Additional ensures for scientific/engineering applications.
+ * @author Joerg <yogi2005@users.sourceforge.net>
+ * @date 07/04/2008
+ */
+#ifndef TUT_Float_H_GUARD
+#define TUT_Float_H_GUARD
+
+#include <limits>
+#include <iostream>
+
+namespace tut
+{
+ namespace detail
+ {
+ template<bool Predicate, typename Then, typename Else>
+ struct If
+ {
+ typedef Else type;
+ };
+
+ template<typename Then, typename Else>
+ struct If<true,Then,Else>
+ {
+ typedef Then type;
+ };
+
+ template<typename T>
+ struct fpt_traits
+ {
+ struct StdNumericLimitsNotAvailable {};
+ static const StdNumericLimitsNotAvailable static_check[ std::numeric_limits<T>::is_specialized ];
+
+ static const T zero;
+
+ typedef typename If<std::numeric_limits<T>::is_integer,
+ double,
+ T>::type Result;
+
+ static T abs(const T &arg)
+ {
+ if(arg < zero)
+ return zero - arg;
+ else
+ return arg;
+ }
+
+ static T sig(const T &arg)
+ {
+ if(arg < zero)
+ return -1;
+ else
+ return 1;
+ }
+
+ static inline Result div(const Result &number, const T &divisor)
+ {
+ static_cast<void>(static_check);
+
+ if(number == zero && divisor == zero)
+ return std::numeric_limits<Result>::quiet_NaN();
+
+ if(number == zero)
+ return zero;
+
+ if(divisor == zero)
+ return sig(number) * std::numeric_limits<Result>::infinity();
+
+ assert(zero < number);
+ assert(zero < divisor);
+
+ // Avoid underflow
+ if(static_cast<T>(1) < abs(divisor))
+ {
+ // number / divisor < min <=> number < min * divisor
+ if( abs(number) < abs(divisor) * std::numeric_limits<T>::min())
+ {
+ return sig(divisor) * sig(number) * std::numeric_limits<T>::min();
+ }
+ }
+
+ // Avoid overflow
+ if( abs(divisor) < static_cast<T>(1))
+ {
+ // number / divisor > max <=> number > max * divisor
+ if( abs(divisor) * std::numeric_limits<T>::max() < abs(number))
+ {
+ return sig(divisor) * sig(number) * std::numeric_limits<T>::max();
+ }
+ }
+
+ return number / divisor;
+ }
+ };
+
+ template<typename T>
+ const typename fpt_traits<T>::StdNumericLimitsNotAvailable
+ fpt_traits<T>::static_check[ std::numeric_limits<T>::is_specialized ] = { {} };
+
+ template<typename T>
+ const T fpt_traits<T>::zero = static_cast<T>(0);
+
+ template<typename T, typename U>
+ bool check_tolerance(T actual, T expected, U fraction)
+ {
+ typename fpt_traits<T>::Result diff = fpt_traits<T>::div( fpt_traits<T>::abs( expected - actual ),
+ fpt_traits<T>::abs( expected ) );
+
+ return (diff == fraction) || (diff < fraction);
+ }
+
+ } // namespace detail
+
+ template<typename T, typename U>
+ void ensure_close(const char* msg, const T& actual, const T& expected, const U& tolerance )
+ {
+ typedef detail::fpt_traits<U> Traits;
+
+ typename Traits::Result fraction = Traits::div( Traits::abs(static_cast<typename Traits::Result>(tolerance)),
+ static_cast<typename Traits::Result>(100) );
+ if( !detail::check_tolerance(actual, expected, fraction) )
+ {
+ std::ostringstream ss;
+ ss << ( msg ? msg : "" )
+ << ( msg ? ": " : "" )
+ << "expected `"
+ << expected
+ << "` and actual `"
+ << actual
+ << "` differ more than "
+ << tolerance
+ << "%";
+ throw failure( ss.str().c_str() );
+ }
+ }
+
+ template<typename T, typename Tolerance>
+ void ensure_close(const T& actual, const T& expected, const Tolerance& tolerance )
+ {
+ ensure_close( 0, actual, expected, tolerance );
+ }
+
+ template<typename T, typename U>
+ void ensure_close_fraction(const char* msg, const T& actual, const T& expected, const U& fraction)
+ {
+ typedef char StdNumericLimitsNotAvailable;
+ const StdNumericLimitsNotAvailable static_check[ std::numeric_limits<U>::is_specialized ] = { 0 };
+ static_cast<void>(static_check);
+
+ typedef typename detail::If<std::numeric_limits<U>::is_integer,
+ double,
+ U>::type Tolerance;
+
+ if( !detail::check_tolerance(actual, expected, fraction) )
+ {
+ std::ostringstream ss;
+ ss << ( msg ? msg : "" )
+ << ( msg ? ": " : "" )
+ << "expected `"
+ << expected
+ << "` and actual `"
+ << actual
+ << "` differ more than fraction `"
+ << fraction
+ << "`";
+ throw failure( ss.str().c_str() );
+ }
+ }
+
+ template<typename T>
+ void ensure_close_fraction( const char* msg, const T& actual, const T& expected, const int& tolerance )
+ {
+ ensure_close(msg, actual, expected, double(tolerance));
+ }
+
+ template< typename T, typename Tolerance>
+ void ensure_close_fraction(const T& actual, const T& expected, const Tolerance& fraction)
+ {
+ ensure_close_fraction( 0, actual, expected, fraction );
+ }
+
+} // namespace tut
+
+#endif
+
--- /dev/null
+#ifndef TUT_MACROS_HPP
+#define TUT_MACROS_HPP
+
+#include <tut/tut.hpp>
+
+#ifdef ensure_THROW
+#error ensure_THROW macro is already defined
+#endif
+
+/** Helper macros to ensure that a call throws exception.
+ * \code
+ * #include <tut_macros.h>
+ * ensure_THROW( this_function_should_throw_bad_alloc(), std::bad_alloc );
+ * \endcode
+ */
+#define ensure_THROW( x, e ) \
+try \
+{ \
+ x; \
+ fail(#x " has not thrown expected exception " #e); \
+} \
+catch(const e &) \
+{ \
+} \
+catch(const std::exception &ex) \
+{ \
+ fail( std::string(#x " has thrown unexpected exception ")+tut::type_name(ex)+": "+ex.what()); \
+} \
+catch(...) \
+{ \
+ fail(#x " has thrown unexpected unknown exception"); \
+}
+
+#ifdef ensure_NO_THROW
+#error ensure_NO_THROW macro is already defined
+#endif
+
+/** Helper macro to ensure a call does not throw any exceptions.
+ * \code
+ * #include <tut_macros.h>
+ * ensure_NO_THROW( this_function_should_never_throw() );
+ * \endcode
+ */
+#define ensure_NO_THROW( x ) \
+try \
+{ \
+ x; \
+} \
+catch(const std::exception &ex) \
+{ \
+ fail( std::string(#x " has thrown unexpected exception ")+tut::type_name(ex)+": "+ex.what()); \
+} \
+catch(...) \
+{ \
+ fail(#x " has thrown unexpected unknown exception"); \
+}
+
+#ifdef __COUNTER__
+#define TUT_TESTCASE(object) template<> template<> void object::test<__COUNTER__>()
+#endif
+
+#endif
+
--- /dev/null
+#ifndef TUT_MAIN_H
+#define TUT_MAIN_H
+
+#include <tut/tut.hpp>
+#include <tut/tut_console_reporter.hpp>
+#include <tut/tut_cppunit_reporter.hpp>
+#include <iostream>
+#include <cstring>
+
+namespace tut
+{
+
+/** Helper function to make test binaries simpler.
+ *
+ * Example of basic usage follows.
+ *
+ * @code
+ * namespace tut { test_runner_singleton runner; }
+ *
+ * int main(int argc, char **argv)
+ * {
+ * if( tut_main(argc, argv) )
+ * return 0;
+ * else
+ * return -1;
+ * }
+ * @endcode
+ *
+ * It is also possible to do some generic initialization before
+ * running any tests and cleanup before exiting application.
+ * Note that tut_main can throw tut::no_such_group or tut::no_such_test.
+ *
+ * @code
+ * namespace tut { test_runner_singleton runner; }
+ *
+ * int main(int argc, char **argv)
+ * {
+ * tut::xml_reporter reporter;
+ * tut::runner.get().insert_callback(&reporter);
+ *
+ * MyInit();
+ * try
+ * {
+ * tut_main(argc, argv);
+ * }
+ * catch(const tut::tut_error &ex)
+ * {
+ * std::cerr << "TUT error: " << ex.what() << std::endl;
+ * }
+ * MyCleanup();
+ * }
+ * @endcode
+ */
+inline bool tut_main(int argc, const char * const * const argv, std::ostream &os = std::cerr)
+{
+ std::stringstream usage;
+ usage << "Usage: " << argv[0] << " [group] [testcase]" << std::endl;
+ groupnames gr = runner.get().list_groups();
+ usage << "Available test groups:" << std::endl;
+ for(groupnames::const_iterator i = gr.begin(); i != gr.end(); ++i)
+ {
+ usage << " " << *i << std::endl;
+ }
+
+ if(argc>1)
+ {
+ if(std::string(argv[1]) == "-h" ||
+ std::string(argv[1]) == "--help" ||
+ std::string(argv[1]) == "/?" ||
+ argc > 3)
+ {
+ os << usage.rdbuf();
+ return false;
+ }
+ }
+
+ // Check command line options.
+ switch(argc)
+ {
+ case 1:
+ runner.get().run_tests();
+ break;
+
+ case 2:
+ runner.get().run_tests(argv[1]);
+ break;
+
+ case 3:
+ {
+ char *end;
+ int t = strtol(argv[2], &end, 10);
+ if(end != argv[2] + strlen(argv[2]))
+ {
+ throw no_such_test("`" + std::string(argv[2]) + "` should be a number");
+ }
+
+ test_result tr;
+ if(!runner.get().run_test(argv[1], t, tr) || tr.result == test_result::dummy)
+ {
+ throw no_such_test("No testcase `" + std::string(argv[2]) + "` in group `" + argv[1] + "`");
+ }
+ }
+ break;
+ }
+
+ return true;
+} // tut_main()
+
+}
+
+#endif
#ifndef TUT_FORK_H_GUARD
#define TUT_FORK_H_GUARD
+#include <tut/tut_config.hpp>
#if defined(TUT_USE_POSIX)
#include <errno.h>
if(tr.result != test_result::ok)
{
- std::stringstream ss;
+ std::ostringstream ss;
ss << int(tr.result) << "\n"
<< tr.group << "\n"
<< tr.test << "\n"
ensure_errno("write() failed", w == size);
}
}
+
+ virtual ~test_group_posix()
+ {
+ }
};
template<typename T>
* Default constructor
*/
test_object_posix()
- : pipe_(-1)
+ : pids_(),
+ pipe_(-1)
{
}
if(!pids_.empty())
{
- std::stringstream ss;
+ std::ostringstream ss;
// in parent, reap children
for(std::map<pid_t, int>::iterator i = pids_.begin(); i != pids_.end(); ++i)
else
{
// cannot kill, we are in trouble
- std::stringstream ss;
+ std::ostringstream ss;
char e[1024];
ss << "child " << pid << " could not be killed with SIGTERM, " << strerror_r(errno, e, sizeof(e)) << std::endl;
fail(ss.str());
}
else
{
- std::stringstream ss;
+ std::ostringstream ss;
char e[1024];
ss << "child " << pid << " could not be killed with SIGKILL, " << strerror_r(errno, e, sizeof(e)) << std::endl;
fail(ss.str());
ensure_equals("child process exists after SIGKILL", ::kill(pid, 0), -1);
- std::stringstream ss;
+ std::ostringstream ss;
ss << "child " << pid << " had to be killed with SIGKILL";
fail(ss.str());
}
{
if(WIFSIGNALED(status))
{
- std::stringstream ss;
+ std::ostringstream ss;
ss << "child killed by signal " << WTERMSIG(status)
<< ": expected exit with code " << exit_status;
{
if(WEXITSTATUS(status) != exit_status)
{
- std::stringstream ss;
+ std::ostringstream ss;
ss << "child exited, expected '"
<< exit_status
<< "' actual '"
if(WIFSTOPPED(status))
{
- std::stringstream ss;
+ std::ostringstream ss;
ss << "child stopped by signal " << WTERMSIG(status)
<< ": expected exit with code " << exit_status;
throw failure(ss.str().c_str());
{
if(WTERMSIG(status) != signal)
{
- std::stringstream ss;
+ std::ostringstream ss;
ss << "child killed by signal, expected '"
<< signal
<< "' actual '"
if(WIFEXITED(status))
{
- std::stringstream ss;
+ std::ostringstream ss;
ss << "child exited with code " << WEXITSTATUS(status)
<< ": expected signal " << signal;
if(WIFSTOPPED(status))
{
- std::stringstream ss;
+ std::ostringstream ss;
ss << "child stopped by signal " << WTERMSIG(status)
<< ": expected kill by signal " << signal;
struct test_object_posix
{
+ virtual ~test_object_posix()
+ {
+ }
};
struct test_group_posix
void send_result_(const T*, const test_result &)
{
}
+
+ virtual ~test_group_posix()
+ {
+ }
};
} // namespace tut
}
return true;
}
-};
+}
/**
* Restartable test runner wrapper.
*/
restartable_wrapper(const std::string& dir = ".")
: runner_(runner.get()),
- dir_(dir)
+ callbacks_(),
+ dir_(dir),
+ log_( dir + '/' + "log.tut" ),
+ jrn_( dir + '/' + "journal.tut" )
{
// dozen: it works, but it would be better to use system path separator
- jrn_ = dir_ + '/' + "journal.tut";
- log_ = dir_ + '/' + "log.tut";
}
/**
#ifndef TUT_RESULT_H_GUARD
#define TUT_RESULT_H_GUARD
+#include <tut/tut_config.hpp>
#include <string>
+#if defined(TUT_USE_RTTI)
+#if (defined(_MSC_VER) && !defined(_CPPRTTI)) || (defined(__GNUC__) && !defined(__GXX_RTTI))
+#undef TUT_USE_RTTI
+#endif
+#endif
+
+#if defined(TUT_USE_RTTI)
+#include <typeinfo>
+#endif
+
namespace tut
{
+#if defined(TUT_USE_RTTI)
+template<typename T>
+inline std::string type_name(const T& t)
+{
+ return typeid(t).name();
+}
+#else
+template<typename T>
+inline std::string type_name(const T& t)
+{
+ return "Unknown type, RTTI disabled";
+}
+
+inline std::string type_name(const std::exception&)
+{
+ return "Unknown std::exception, RTTI disabled";
+}
+#endif
+
+
#if defined(TUT_USE_POSIX)
struct test_result_posix
{
{
}
+ virtual ~test_result_posix()
+ {
+ }
+
pid_t pid;
};
#else
struct test_result_posix
{
+ virtual ~test_result_posix()
+ {
+ }
};
#endif
std::string name;
/**
- * ok - test finished successfully
- * fail - test failed with ensure() or fail() methods
- * ex - test throwed an exceptions
- * warn - test finished successfully, but test destructor throwed
- * term - test forced test application to terminate abnormally
+ * result of a test
*/
enum result_type
{
- ok,
- fail,
- ex,
- warn,
- term,
- ex_ctor,
- rethrown,
- dummy
+ ok, ///< test finished successfully
+ fail, ///< test failed with ensure() or fail() methods
+ ex, ///< test throwed an exceptions
+ warn, ///< test finished successfully, but test destructor throwed
+ term, ///< test forced test application to terminate abnormally
+ ex_ctor, ///<
+ rethrown, ///<
+ skipped, ///<
+ dummy ///<
};
result_type result;
* Default constructor.
*/
test_result()
- : test(0),
- result(ok)
+ : group(),
+ test(0),
+ name(),
+ result(ok),
+ message(),
+ exception_typeid()
{
}
: group(grp),
test(pos),
name(test_name),
- result(res)
+ result(res),
+ message(),
+ exception_typeid()
{
}
name(test_name),
result(res),
message(ex.what()),
- exception_typeid(typeid(ex).name())
+ exception_typeid(type_name(ex))
{
}
exception_typeid(ex_typeid)
{
}
+
+ virtual ~test_result()
+ {
+ }
};
}
* Called when a group started
* @param name Name of the group
*/
- virtual void group_started(const std::string& /*name*/)
+ virtual void group_started(const std::string& name)
{
+ (void)name;
}
/**
* Called when a test finished.
* @param tr Test results.
*/
- virtual void test_completed(const test_result& /*tr*/)
+ virtual void test_completed(const test_result& tr)
{
+ (void)tr;
}
/**
* Called when a group is completed
* @param name Name of the group
*/
- virtual void group_completed(const std::string& /*name*/)
+ virtual void group_completed(const std::string& name)
{
+ (void)name;
}
/**
virtual void run_completed()
{
}
+
+ virtual bool all_ok() const
+ {
+ return true;
+ }
private:
callback(const callback &);
void operator=(const callback&);
* Constructor
*/
test_runner()
+ : groups_(),
+ callbacks_()
{
}
/**
* Stores another group for getting by name.
+ * @param name new group object
+ * @param gr new callback object
*/
void register_group(const std::string& name, group_base* gr)
{
if (groups_.find(name) != groups_.end())
{
std::string msg("attempt to add already existent group " + name);
- // this exception terminates application so we use cerr also
- // TODO: should this message appear in stream?
- std::cerr << msg << std::endl;
throw tut_error(msg);
}
groups_.insert( std::make_pair(name, gr) );
}
+ /**
+ * Stores one callback object.
+ * @param cb new callback object
+ */
void set_callback(callback *cb)
{
clear_callbacks();
}
/**
- * Stores callback object.
+ * Add callback object.
+ * @param cb new callback object
*/
void insert_callback(callback* cb)
{
}
}
+ /**
+ * Remove callback object.
+ * @param cb callback to remove
+ */
void erase_callback(callback* cb)
{
callbacks_.erase(cb);
}
+ /**
+ * Remove all callback objects.
+ */
void clear_callbacks()
{
callbacks_.clear();
/**
* Returns callback list.
+ * @return callback list
*/
const callbacks &get_callbacks() const
{
return callbacks_;
}
+ /**
+ * Set callback list.
+ * @param cb new callback list
+ */
void set_callbacks(const callbacks &cb)
{
callbacks_ = cb;
/**
* Returns list of known test groups.
+ * @return groups list
*/
const groupnames list_groups() const
{
groupnames ret;
- const_iterator i = groups_.begin();
- const_iterator e = groups_.end();
- while (i != e)
+ for(const_iterator i = groups_.begin(); i != groups_.end(); ++i)
{
ret.push_back(i->first);
- ++i;
}
return ret;
}
/**
* Runs all tests in all groups.
- * @param callback Callback object if exists; null otherwise
*/
void run_tests() const
{
/**
* Runs all tests in specified group.
+ * @param group_name group to test
*/
void run_tests(const std::string& group_name) const
{
/**
* Runs one test in specified group.
+ * @param group_name group to test
+ * @param n run case in test
+ * @param tr result of this case
+ * @return true if test is ok, otherwise false
*/
bool run_test(const std::string& group_name, int n, test_result &tr) const
{
}
-#endif
+#endif // TUT_RUNNER_H_GUARD
+
-/*
- * tut_xml_reporter.hpp
- *
- * ECOS Library. IPT CS R&D CET ECOS Copyright 2008 Nokia
- * Siemens Networks. All right
- *
- *
- */
-
#ifndef TUT_XML_REPORTER
#define TUT_XML_REPORTER
-
+#include <tut/tut_config.hpp>
#include <tut/tut.hpp>
+#include <tut/tut_cppunit_reporter.hpp>
+#include <cassert>
#include <string>
#include <fstream>
#include <vector>
*/
class xml_reporter : public tut::callback
{
-protected:
typedef std::vector<tut::test_result> TestResults;
typedef std::map<std::string, TestResults> TestGroups;
- TestGroups all_tests; /// holds all test results
- std::string filename; /// filename base
-
- /**
- * \brief Initializes object
- * Resets counters and clears all stored test results.
- */
- virtual void init()
- {
- ok_count = 0;
- exceptions_count = 0;
- failures_count = 0;
- terminations_count = 0;
- warnings_count = 0;
- all_tests.clear();
- }
-
- /**
- * \brief Encodes text to XML
- * XML-reserved characters (e.g. "<") are encoded according to specification
- * @param text text to be encoded
- * @return encoded string
- */
- virtual std::string encode(const std::string & text)
- {
- std::string out;
-
- for (unsigned int i=0; i<text.length(); ++i) {
- char c = text[i];
- switch (c) {
- case '<':
- out += "<";
- break;
- case '>':
- out += ">";
- break;
- case '&':
- out += "&";
- break;
- case '\'':
- out += "'";
- break;
- case '"':
- out += """;
- break;
- default:
- out += c;
- }
- }
-
- return out;
- }
+ TestGroups all_tests_; /// holds all test results
+ const std::string filename_; /// filename base
+ std::auto_ptr<std::ostream> stream_;
/**
* \brief Builds "testcase" XML entity with given parameters
* @param failure_msg failure message to be reported (empty, if test passed)
* @return string with \<testcase\> entity
*/
- virtual std::string xml_build_testcase(const tut::test_result & tr, const std::string & failure_type,
+ std::string xml_build_testcase(const tut::test_result & tr, const std::string & failure_type,
const std::string & failure_msg, int pid = 0)
{
using std::endl;
std::ostringstream out;
- if (tr.result == test_result::ok)
+ if ( (tr.result == test_result::ok) ||
+ (tr.result == test_result::skipped) )
{
- out << " <testcase classname=\"" << encode(tr.group) << "\" name=\"" << encode(tr.name) << "\" />";
+ out << " <testcase classname=\"" << cppunit_reporter::encode(tr.group) << "\" name=\"" << cppunit_reporter::encode(tr.name) << "\"/>";
}
else
{
- string err_msg = encode(failure_msg + tr.message);
+ string err_msg = cppunit_reporter::encode(failure_msg + tr.message);
string tag; // determines tag name: "failure" or "error"
if ( tr.result == test_result::fail || tr.result == test_result::warn ||
- tr.result == test_result::ex || tr.result == test_result::ex_ctor )
+ tr.result == test_result::ex || tr.result == test_result::ex_ctor || tr.result == test_result::rethrown )
{
tag = "failure";
}
tag = "error";
}
- out << " <testcase classname=\"" << encode(tr.group) << "\" name=\"" << encode(tr.name) << "\">" << endl;
- out << " <" << tag << " message=\"" << err_msg << "\"" << " type=\"" << failure_type << "\"";
+ out << " <testcase classname=\"" << cppunit_reporter::encode(tr.group) << "\" name=\"" << cppunit_reporter::encode(tr.name) << "\">" << endl;
+ out << " <" << tag << " message=\"" << err_msg << "\"" << " type=\"" << failure_type << "\"";
#if defined(TUT_USE_POSIX)
if(pid != getpid())
{
out << " child=\"" << pid << "\"";
}
+#else
+ (void)pid;
#endif
out << ">" << err_msg << "</" << tag << ">" << endl;
- out << " </testcase>";
+ out << " </testcase>";
}
return out.str();
* @param failures number of failures to be reported
* @param total total number of tests to be reported
* @param name test suite name
- * @param testcases encoded XML string containing testcases
+ * @param testcases cppunit_reporter::encoded XML string containing testcases
* @return string with \<testsuite\> entity
*/
- virtual std::string xml_build_testsuite(int errors, int failures, int total,
+ std::string xml_build_testsuite(int errors, int failures, int total,
const std::string & name, const std::string & testcases)
{
std::ostringstream out;
- out << "<testsuite errors=\"" << errors << "\" failures=\"" << failures << "\" tests=\"" << total << "\" name=\"" << encode(name) << "\">" << std::endl;
+ out << " <testsuite errors=\"" << errors << "\" failures=\"" << failures << "\" tests=\"" << total << "\" name=\"" << cppunit_reporter::encode(name) << "\">" << std::endl;
out << testcases;
- out << "</testsuite>";
+ out << " </testsuite>";
return out.str();
}
/**
* \brief Default constructor
* @param filename base filename
- * @see setFilenameBase
*/
- xml_reporter(const std::string & _filename = "")
+ xml_reporter(const std::string & filename)
+ : all_tests_(),
+ filename_(filename),
+ stream_(new std::ofstream(filename_.c_str())),
+ ok_count(0),
+ exceptions_count(0),
+ failures_count(0),
+ terminations_count(0),
+ warnings_count(0)
{
- init();
- setFilenameBase(_filename);
+ if (!stream_->good()) {
+ throw tut_error("Cannot open output file `" + filename_ + "`");
+ }
}
- /**
- * \brief Sets filename base for output
- * @param _filename filename base
- * Example usage:
- * @code
- * xml_reporter reporter;
- * reporter.setFilenameBase("my_xml");
- * @endcode
- * The above code will instruct reporter to create my_xml_1.xml file for the first test group,
- * my_xml_2.xml file for the second, and so on.
- */
- virtual void setFilenameBase(const std::string & _filename)
+ xml_reporter(std::ostream & stream)
+ : all_tests_(),
+ filename_(),
+ stream_(&stream),
+ ok_count(0),
+ exceptions_count(0),
+ failures_count(0),
+ terminations_count(0),
+ warnings_count(0)
{
- if (_filename == "")
- {
- filename = "testResult";
- }
- else
- {
- if (_filename.length() > 200)
- {
- throw(std::runtime_error("Filename too long!"));
- }
+ }
- filename = _filename;
+ ~xml_reporter()
+ {
+ if(filename_.empty())
+ {
+ stream_.release();
}
}
*/
virtual void run_started()
{
- init();
+ ok_count = 0;
+ exceptions_count = 0;
+ failures_count = 0;
+ terminations_count = 0;
+ warnings_count = 0;
+ all_tests_.clear();
}
/**
// update global statistics
switch (tr.result) {
case test_result::ok:
+ case test_result::skipped:
ok_count++;
break;
case test_result::fail:
case test_result::term:
terminations_count++;
break;
+ case tut::test_result::dummy:
+ assert(!"Should never be called");
} // switch
// add test result to results table
- (all_tests[tr.group]).push_back(tr);
+ all_tests_[tr.group].push_back(tr);
}
/**
* \brief Callback function
* This function is called when all tests are completed. It generates XML output
- * to file(s). File name base can be set with \ref setFilenameBase.
+ * to file(s). File name base can be set with constructor.
*/
virtual void run_completed()
{
- using std::endl;
- using std::string;
-
- static int number = 1; // results file sequence number (testResult_<number>.xml)
+ /* *********************** header ***************************** */
+ *stream_ << "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>" << std::endl;
+ *stream_ << "<testsuites>" << std::endl;
// iterate over all test groups
- TestGroups::const_iterator tgi;
- for (tgi = all_tests.begin(); tgi != all_tests.end(); ++tgi) {
+ for (TestGroups::const_iterator tgi = all_tests_.begin(); tgi != all_tests_.end(); ++tgi)
+ {
/* per-group statistics */
int passed = 0; // passed in single group
int exceptions = 0; // exceptions in single group
int failures = 0; // failures in single group
int terminations = 0; // terminations in single group
int warnings = 0; // warnings in single group
- int errors = 0; // errors in single group
+ int errors = 0; // errors in single group
- /* generate output filename */
- char fn[256];
- sprintf(fn, "%s_%d.xml", filename.c_str(), number++);
-
- std::ofstream xmlfile;
- xmlfile.open(fn, std::ios::in | std::ios::trunc);
- if (!xmlfile.is_open()) {
- throw (std::runtime_error("Cannot open file for output"));
- }
-
- /* *********************** header ***************************** */
- xmlfile << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << endl;
// output is written to string stream buffer, because JUnit format <testsuite> tag
// contains statistics, which aren't known yet
std::ostringstream out;
// iterate over all test cases in the current test group
- TestResults::const_iterator tri;
- for (tri = (*tgi).second.begin(); tri != (*tgi).second.end(); ++tri) {
- string failure_type; // string describing the failure type
- string failure_msg; // a string with failure message
+ const TestResults &results = tgi->second;
+ for (TestResults::const_iterator tri = results.begin(); tri != results.end(); ++tri)
+ {
+ std::string failure_type; // string describing the failure type
+ std::string failure_msg; // a string with failure message
- switch ((*tri).result) {
+ switch (tri->result)
+ {
case test_result::ok:
+ case test_result::skipped:
passed++;
break;
case test_result::fail:
break;
case test_result::ex:
failure_type = "Assertion";
- failure_msg = "Thrown exception: " + (*tri).exception_typeid + '\n';
+ failure_msg = "Thrown exception: " + tri->exception_typeid + '\n';
exceptions++;
break;
case test_result::warn:
break;
case test_result::ex_ctor:
failure_type = "Assertion";
- failure_msg = "Constructor has thrown an exception: " + (*tri).exception_typeid + '\n';
+ failure_msg = "Constructor has thrown an exception: " + tri->exception_typeid + ".\n";
exceptions++;
break;
case test_result::rethrown:
failure_type = "Assertion";
- failure_msg = "Child failed";
+ failure_msg = "Child failed.\n";
failures++;
break;
default:
failure_type = "Error";
failure_msg = "Unknown test status, this should have never happened. "
- "You may just have found a BUG in TUT XML reporter, please report it immediately.\n";
+ "You may just have found a bug in TUT, please report it immediately.\n";
errors++;
break;
} // switch
#if defined(TUT_USE_POSIX)
- out << xml_build_testcase(*tri, failure_type, failure_msg, (*tri).pid) << endl;
+ out << xml_build_testcase(*tri, failure_type, failure_msg, tri->pid) << std::endl;
#else
- out << xml_build_testcase(*tri, failure_type, failure_msg) << endl;
+ out << xml_build_testcase(*tri, failure_type, failure_msg) << std::endl;
#endif
-
} // iterate over all test cases
// calculate per-group statistics
int stat_failures = failures + warnings + exceptions;
int stat_all = stat_errors + stat_failures + passed;
- xmlfile << xml_build_testsuite(stat_errors, stat_failures, stat_all, (*tgi).first/* name */, out.str()/* testcases */) << endl;
- xmlfile.close();
+ *stream_ << xml_build_testsuite(stat_errors, stat_failures, stat_all, (*tgi).first/* name */, out.str()/* testcases */) << std::endl;
} // iterate over all test groups
+
+ *stream_ << "</testsuites>" << std::endl;
}
/**
+++ /dev/null
-
-#include <tut/tut_console_reporter.hpp>
-#include <tut/tut_cppunit_reporter.hpp>
-#include <tut/tut_xml_reporter.hpp>
-#include <tut/tut_reporter.hpp>
+++ /dev/null
-
-#include <tut/tut_restartable.hpp>