Как генерировать сетевые пакеты с помощью C/C++

Я хочу сгенерировать сетевой пакет для отправки (например) через порт 123 на сервер NTP, чтобы я мог получить и проанализировать возвращенный пакет. Цель состоит в том, чтобы лучше понять, как сетевые системы генерируют пакеты, считывают их и отвечают на них.

(1) Следует ли использовать структуру для генерации пакета?

(2) я не знаю, как правильно заполнить различные поля в структуре; например, должны ли исходный и конечный IP-адреса быть установлены с шестнадцатеричными значениями? Или есть более гуманный способ?

(3) Затем, после заполнения полей, можно ли отправить структуру через send()/write() через соединение UDP с сервером NTP? (или TCP, если этого требует протокол)

Разумен ли мой подход? Я читал NTP RFC, но до сих пор не уверен, что мой клиент должен отправлять на сервер (например, IP-адрес; разве об этом не должен заботиться заголовок сетевого уровня?) Я смоделировал этот NTP struct после примера «передачи» в Приложении A к RFC 5905. Я прошу прощения, если мой вопрос плохо сформулирован или слишком длинный. Спасибо заранее за любую помощь. Пример кода ниже заимствован из примера кода в RFC 5905.

typedef unsigned long ipaddr;       //32 bits (4 bytes)
typedef signed char s_char;     //character type as number, -128..127
typedef unsigned int tdist;     //character type as number, 0..255
typedef unsigned long long tstamp;  //64 bits (8 bytes)
typedef unsigned long digest;       //32 bits (4 bytes)

struct Ntp {
    ipaddr  dstaddr;
    ipaddr  srcaddr;
    char    version;
    char    leap;
    char    mode;
    char    stratum;
    char    poll;
    s_char  precision;
    tdist   rootdelay;
    tdist   rootdisp;
    char    refid;
    tstamp  reftime;
    tstamp  org;
    tstamp  rec;
    tstamp  xmt;
    int     keyid;
    digest  dgst;
} Ntp;

int main()
{
    struct Ntp packet;

    //packet.dstaddr=WHAT_GOES_HERE;
    //...
    //...
    //packet.dgst=WHAT_GOES_HERE;

    return 0;
}

person shelladept    schedule 24.06.2011    source источник
comment
Вы уверены, что ваша структура Ntp не дополняется непредсказуемым образом?   -  person Kerrek SB    schedule 25.06.2011
comment
если IP-адреса источника и получателя должны быть установлены с шестнадцатеричными значениями - конечно, нет, хотя они были бы предпочтительнее при использовании IPv6. C имеет десятичные литералы, функции анализа десятичных знаков и функции анализа IP (зависит от платформы, см. руководство по вашей ОС).   -  person Fred Foo    schedule 25.06.2011
comment
Возможно, вам придется настроить порядок байтов любых многобайтовых величин, которые вы отправляете по сети, что является еще одной причиной избегать отправки всей структуры за одну запись.   -  person Jim Lewis    schedule 25.06.2011
comment
@Kerrek SB -- Нет, я не уверен, так как я еще не заполнил каждый раздел пакета, хотя я уверен, что это проблема, с которой я столкнусь.   -  person shelladept    schedule 25.06.2011
comment
@Iarsmans - спасибо за предложение, я рассмотрю функции синтаксического анализа, поддерживаемые C.   -  person shelladept    schedule 25.06.2011
comment
@ Джим Льюис - вы имеете в виду ситуацию, когда пакет может быть фрагментирован? Не могли бы вы уточнить, что такое «многобайтовое количество», отправляемое по сети? Спасибо за ваш отзыв   -  person shelladept    schedule 25.06.2011
comment
@shelladept, если вам нужен простой сетевой протокол для кодирования, напишите для echo protocol   -  person This    schedule 25.06.2011
comment
@shelladept: Нет, фрагментация происходит на уровне, который вам, как сетевому программисту, редко приходится учитывать. Но протоколы, с которыми вы пытаетесь взаимодействовать, обычно имеют очень специфические требования к форматированию ваших данных, и это может не соответствовать тому, как ваш компилятор размещает структуры в памяти. Это то, что Керрек имел в виду в отношении заполнения, и то, что я имел в виду в отношении порядка байтов (самый младший или самый значащий байт первым, по сети, для 16-битного или более широкого количества). Хороший вопрос!   -  person Jim Lewis    schedule 25.06.2011
comment
@Mike Pennington: Спасибо за предложение, я попробую написать для более простого протокола.   -  person shelladept    schedule 27.06.2011
comment
@ Джим Льюис: Спасибо, что расширили свое предыдущее предложение; Я ценю детали вашего ответа. Это очень полезно.   -  person shelladept    schedule 27.06.2011


Ответы (1)


Похоже, у вас нет большого опыта написания сетевых протоколов. Объявление структуры и запись ее — не выход. Я также указываю вам на http://fixunix.com/ntp/257876-any-samples-ntp-sntp-client-code.html и особо выделить следующие пункты:

  • Почему вы хотите использовать свой собственный, а не один из существующих пакетов?

  • Одной из проблем при написании клиента NTP является правильное определение времени.

  • Другой — не портить остальную часть сети и не создавать чрезмерную нагрузку на серверы.

В любом случае, как обсуждалось в треде, на который я вам указал, вы хотите использовать SNTP и должны взглянуть на эталонную реализацию SNTP в архиве ntp, чтобы указать путь и помочь вам понять, что вам следует делать.

person Seth Robertson    schedule 25.06.2011
comment
Спасибо за ответ; моя цель — лучше понять, как пакеты отправляются, читаются и на них отвечают системы по сети (на самом базовом уровне). Я не пытаюсь сделать общедоступного клиента — я просто хочу успешно отправить пакет, соответствующий протоколу. В этом случае НТП; Я выбрал его, потому что думал [возможно, ошибочно], что это будет более реалистичная цель. Я предполагаю, что мой вопрос не точно рекламирует мою цель, и я приношу извинения за любую путаницу; спасибо за ваш конструктивный ответ - я соответствующим образом отредактирую свой вопрос. - person shelladept; 25.06.2011