Модераторы: feodorv
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> ICMP пакет, ICMP пакет 
V
    Опции темы
Alexey68
Дата 2.12.2015, 13:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 98
Регистрация: 10.4.2013

Репутация: нет
Всего: нет



Здравствуйте!
При попытке пинга роутера, ответ приходит, но с внешнего узла ответа нет.
В чём может быть причина?
Структуры:
Код

#pragma pack(push,1)
//Ethernet Header
typedef struct ethernet_header
{
    UCHAR dest[6]; //Total 48 bits
    UCHAR source[6]; //Total 48 bits
    USHORT type; //16 bits
}ETH_HDR;
#pragma pack(pop)

#pragma pack(push,1)
typedef struct IP_header
{
    unsigned char  ver;
    unsigned char ServicesField;
    unsigned short TotalLength;
    unsigned short Identification;
    unsigned short FragmentFlags;
    unsigned char  TimeToLive;
    unsigned char  NextProtocol;
    unsigned short Checksum;
    unsigned int   ip_srcaddr;   // Source address
    unsigned int   ip_destaddr;  // Destination address
}IP_HDR;
#pragma pack(pop)

#pragma pack(push,1)
typedef struct ICMP_HEADER
{
unsigned char type;
unsigned char code;
unsigned short checksum;
unsigned short id;
unsigned short seqno;
}ICMP_HDR;
#pragma pack(pop)



........................
Код

unsigned char Data_ICMP[32] = {0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69};



//
char ip[16];
unsigned char s_mac[6], d_mac[6], packet[0x4A];
char *temp_packet;
ETH_HDR eth_header;
IP_HDR  ip_header;
ICMP_HEADER ping_header;
//
FILE *in, *out, *last;
char ip_source[] = "192.168.0.13";//адрес сетевой карты
//char ip_dest[16];
char ip_dest[] = "192.168.0.1";//адрес роутера


DWORD pcap;
////////////////////////
HANDLE hThread;//Поток
DWORD  dwThreadId;// Id потока
//


USHORT Checksum(PUCHAR Data, USHORT Length )
{
    ULONG Sum = 0;
    USHORT ShortSum = 0;
    PUSHORT WordData = (PUSHORT) Data;
    USHORT WordCount = Length >> 1;

    while( WordCount-- )
        Sum += *WordData++;

    if( Length & 1 )
        Sum += *(PUCHAR)WordData;

    Sum = (USHORT) Sum + (Sum >> 16) & 0xFFFF;
    ShortSum = (USHORT) Sum + (USHORT)(Sum >> 16);
    
    return (ShortSum != 0xFFFF) ? ~ShortSum : ShortSum;
}

/////////////////

DWORD WINAPI scan(LPVOID param)
{

//Заполнение пакета  Ethernet
memcpy(&eth_header.dest, d_mac, 6);
memcpy(&eth_header.source, s_mac, 6);
eth_header.type = htons(0x0800);
//Заполнение структуры IP header
ip_header.ver = 0x45;
ip_header.ServicesField = 0;
ip_header.TotalLength = htons(sizeof(ip_header)+sizeof(ping_header)+sizeof(Data_ICMP));
ip_header.Identification = htons(27601);
ip_header.FragmentFlags = htons(0);
ip_header.TimeToLive = 0x80;
ip_header.NextProtocol = 0x01;//0x06
ip_header.Checksum = 0;
ip_header.ip_srcaddr = inet_addr(ip_source);
ip_header.ip_destaddr = inet_addr(ip_dest);

//ICMP
ping_header.type = 0x8;
ping_header.code = htons(0x00);
ping_header.checksum = 0;
ping_header.id = htons(0x200);
ping_header.seqno = htons(0x1E00);

ping_header.checksum = Checksum((char*)&ping_header, sizeof(ping_header));
//расчёт контрольной суммы ip header
ip_header.Checksum = Checksum((char*)&ip_header, sizeof(ip_header));

////////
printf("Build packet\n");
memcpy(packet, &eth_header, sizeof(eth_header));
memcpy(packet+sizeof(eth_header), &ip_header, sizeof(ip_header));
memcpy(packet+sizeof(eth_header)+sizeof(ip_header),&ping_header, sizeof(ping_header));
memcpy(packet+sizeof(eth_header)+sizeof(ip_header)+sizeof(ping_header), Data_ICMP, 32);

//Отправка пакета
pcap_sendpacket(adhandle , packet, sizeof(eth_header)+sizeof(ip_header)+sizeof(ping_header)+sizeof(Data_ICMP));

//printf(".");
ExitThread(0);
return 0;
}


void main()
{
FILE *in, *out;
in = fopen("ip.txt", "rb");

memset(packet, '.', sizeof(packet));
//mac роутера
d_mac[0] = 0x*;
d_mac[1] = 0x*;
d_mac[2] = 0x*;
d_mac[3] = 0x*;
d_mac[4] = 0x*;
d_mac[5] = 0x*;
//mac моей сетевой карты
s_mac[0] = 0x*;
s_mac[1] = 0x*;
s_mac[2] = 0x*;
s_mac[3] = 0x*;
s_mac[4] = 0x*;
s_mac[5] = 0x*;


Init_Pcap();//Инициализация интерфейса WinPcap
   Sleep(500);

while (!feof(in))
{
fscanf(in,"%s\n",&ip_dest);
printf("\nNext %s\n", ip_dest);

hThread = CreateThread(NULL, 0, scan,
          (LPVOID)scan, 0, &dwThreadId);
          Sleep(10);
 WaitForSingleObject(hThread, 0);
   CloseHandle(hThread);
 Sleep(1);
}

fclose(in);
free(packet);

system("pause");
}

Прошу Вашей помощи.

PM MAIL   Вверх
feodorv
Дата 2.12.2015, 19:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2213
Регистрация: 30.7.2011

Репутация: 10
Всего: 45



Цитата(Alexey68 @  2.12.2015,  13:20 Найти цитируемый пост)
с внешнего узла ответа нет

Внешний узел пингуется утилитой ping?

Добавлено через 6 минут и 36 секунд
Цитата(Alexey68 @  2.12.2015,  13:20 Найти цитируемый пост)
//mac роутера
d_mac[0] = 0x*;
d_mac[1] = 0x*;
d_mac[2] = 0x*;
d_mac[3] = 0x*;
d_mac[4] = 0x*;
d_mac[5] = 0x*;

Здесь должен быть mac-адрес внешнего узла (соответствующий IP-адресу ip_dest), не роутера. А как у Вас?


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
Alexey68
Дата 2.12.2015, 20:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 98
Регистрация: 10.4.2013

Репутация: нет
Всего: нет



Цитата(feodorv @  2.12.2015,  19:13 Найти цитируемый пост)
Внешний узел пингуется утилитой ping?

да

Цитата(feodorv @  2.12.2015,  19:13 Найти цитируемый пост)
Здесь должен быть mac-адрес внешнего узла (соответствующий IP-адресу ip_dest), не роутера. А как у Вас? 

у меня mac роутера. 
При просмотре пакета в Microsoft Network Monitor 3.4 (использовал стандартный ping)  в заголовке ethernet header присутствует именно mac моей сетевой карты и mac роутера.

Это сообщение отредактировал(а) Alexey68 - 2.12.2015, 22:11
PM MAIL   Вверх
feodorv
Дата 3.12.2015, 06:14 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2213
Регистрация: 30.7.2011

Репутация: 10
Всего: 45



Цитата(Alexey68 @  2.12.2015,  20:31 Найти цитируемый пост)
у меня mac роутера. 

Ну да, правильно, я глупость написал. Внешний узел на то и внешний, что с ним работаем через роутер. А Вы тогда не могли бы сравнить пакеты (по заголовкам), генерируемые Вашей программой и программой ping.


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
feodorv
Дата 3.12.2015, 06:57 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2213
Регистрация: 30.7.2011

Репутация: 10
Всего: 45



Пришлось покопаться в коде.
Цитата(Alexey68 @  2.12.2015,  13:20 Найти цитируемый пост)
ping_header.checksum = Checksum((char*)&ping_header, sizeof(ping_header));

Насколько я понимаю, контрольная сумма в ICMP пакете касается всего сообщения ICMP (то есть включая данные), а не исключительно заголовка ICMP.

Это сообщение отредактировал(а) feodorv - 3.12.2015, 06:58


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
Alexey68
Дата 3.12.2015, 13:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 98
Регистрация: 10.4.2013

Репутация: нет
Всего: нет



Цитата(feodorv @  3.12.2015,  06:14 Найти цитируемый пост)
А Вы тогда не могли бы сравнить пакеты (по заголовкам), генерируемые Вашей программой и программой ping. 

Всё "один в один" кроме контр. суммы.

Цитата(feodorv @  3.12.2015,  06:57 Найти цитируемый пост)
Насколько я понимаю, контрольная сумма в ICMP пакете касается всего сообщения ICMP (то есть включая данные)

Изначально так и делал:
Код

ping_header.checksum = Checksum((char*)&ping_header, sizeof(ping_header)+sizeof(Data_ICMP));

но ответа от хоста так и нет...

Это сообщение отредактировал(а) Alexey68 - 3.12.2015, 14:02

Присоединённый файл ( Кол-во скачиваний: 1 )
Присоединённый файл  packets.rar 0,51 Kb
PM MAIL   Вверх
feodorv
Дата 3.12.2015, 17:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2213
Регистрация: 30.7.2011

Репутация: 10
Всего: 45



Цитата(Alexey68 @  3.12.2015,  13:30 Найти цитируемый пост)
но ответа от хоста так и нет...

Так у Вас данные и заголовок находятся в разных местах памяти. Заглядывать за пределы ping_header - значит выйти за пределы массива байт, отведённых для ping_header. И хотя память за пределами ping_header доступна на чтение (если нет, то Ваша программа просто завершилась бы с криком об ошибке), но там находится мусор. ЦРЦ мусора не очень годится...


Почему бы весь пакет сразу не оформить единым массивом байт:
Код

unsigned char buf[sizeof(struct ethernet_header) + sizeof(struct IP_header)+sizeof(struct ICMP_HEADER)+sizeof(Data_ICMP)];

struct ethernet_header *eth_header = (struct ethernet_header *) buf;
struct IP_header *ip_header = (struct IP_header *) &eth_header[1];
struct ICMP_HEADER *ping_header = (struct ICMP_HEADER *) &ip_header[1];
unsigned char *data_ptr = (unsigned char *) &ping_header[1];

//Заполнение пакета  Ethernet
memcpy( eth_header->dest, d_mac, 6);
...

//Заполнение структуры IP header
ip_header->ver = 0x45;
...

//ICMP
ping_header->type = 0x8;
...

// Data
memcpy( data_ptr, Data_ICMP, sizeof(Data_ICMP));

// CRC
ip_header->Checksum = Checksum( (char*) ip_header, sizeof(struct IP_header));
ping_header->checksum = Checksum( (char*) ping_header, sizeof(struct ICMP_HEADER)+sizeof(Data_ICMP));


Это сообщение отредактировал(а) feodorv - 3.12.2015, 17:24


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
Alexey68
Дата 10.12.2015, 04:32 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 98
Регистрация: 10.4.2013

Репутация: нет
Всего: нет



feodorv, благодарю за помощь!

PM MAIL   Вверх
Google
  Дата 22.5.2019, 12:02 (ссылка)  





  Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Сети | Следующая тема »


 




[ Время генерации скрипта: 0.1676 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.